Make graph dumps use graphviz format
[official-gcc.git] / gcc / ipa-prop.cc
blobb57f9750431195114e6e1d0ca2cceacd97e01eed
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 = 0;
1374 tree base = get_addr_base_and_unit_offset (TREE_OPERAND (op, 0),
1375 &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 && Value_Range::supports_type_p (TREE_TYPE (arg))
2396 && Value_Range::supports_type_p (param_type)
2397 && irange::supports_p (TREE_TYPE (arg))
2398 && irange::supports_p (param_type)
2399 && get_range_query (cfun)->range_of_expr (vr, arg, cs->call_stmt)
2400 && !vr.undefined_p ())
2402 Value_Range resvr (vr);
2403 range_cast (resvr, param_type);
2404 if (!resvr.undefined_p () && !resvr.varying_p ())
2405 ipa_set_jfunc_vr (jfunc, resvr);
2406 else
2407 gcc_assert (!jfunc->m_vr);
2409 else
2410 gcc_assert (!jfunc->m_vr);
2413 if (is_gimple_ip_invariant (arg)
2414 || (VAR_P (arg)
2415 && is_global_var (arg)
2416 && TREE_READONLY (arg)))
2417 ipa_set_jf_constant (jfunc, arg, cs);
2418 else if (!is_gimple_reg_type (TREE_TYPE (arg))
2419 && TREE_CODE (arg) == PARM_DECL)
2421 int index = ipa_get_param_decl_index (info, arg);
2423 gcc_assert (index >=0);
2424 /* Aggregate passed by value, check for pass-through, otherwise we
2425 will attempt to fill in aggregate contents later in this
2426 for cycle. */
2427 if (parm_preserved_before_stmt_p (fbi, index, call, arg))
2429 ipa_set_jf_simple_pass_through (jfunc, index, false);
2430 continue;
2433 else if (TREE_CODE (arg) == SSA_NAME)
2435 if (SSA_NAME_IS_DEFAULT_DEF (arg))
2437 int index = ipa_get_param_decl_index (info, SSA_NAME_VAR (arg));
2438 if (index >= 0)
2440 bool agg_p;
2441 agg_p = parm_ref_data_pass_through_p (fbi, index, call, arg);
2442 ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
2445 else
2447 gimple *stmt = SSA_NAME_DEF_STMT (arg);
2448 if (is_gimple_assign (stmt))
2449 compute_complex_assign_jump_func (fbi, info, jfunc,
2450 call, stmt, arg, param_type);
2451 else if (gimple_code (stmt) == GIMPLE_PHI)
2452 compute_complex_ancestor_jump_func (fbi, info, jfunc,
2453 call,
2454 as_a <gphi *> (stmt));
2458 /* If ARG is pointer, we cannot use its type to determine the type of aggregate
2459 passed (because type conversions are ignored in gimple). Usually we can
2460 safely get type from function declaration, but in case of K&R prototypes or
2461 variadic functions we can try our luck with type of the pointer passed.
2462 TODO: Since we look for actual initialization of the memory object, we may better
2463 work out the type based on the memory stores we find. */
2464 if (!param_type)
2465 param_type = TREE_TYPE (arg);
2467 if ((jfunc->type != IPA_JF_PASS_THROUGH
2468 || !ipa_get_jf_pass_through_agg_preserved (jfunc))
2469 && (jfunc->type != IPA_JF_ANCESTOR
2470 || !ipa_get_jf_ancestor_agg_preserved (jfunc))
2471 && (AGGREGATE_TYPE_P (TREE_TYPE (arg))
2472 || POINTER_TYPE_P (param_type)))
2473 determine_known_aggregate_parts (fbi, call, arg, param_type, jfunc);
2475 if (!useful_context)
2476 vec_free (args->polymorphic_call_contexts);
2479 /* Compute jump functions for all edges - both direct and indirect - outgoing
2480 from BB. */
2482 static void
2483 ipa_compute_jump_functions_for_bb (struct ipa_func_body_info *fbi, basic_block bb)
2485 struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
2486 int i;
2487 struct cgraph_edge *cs;
2489 FOR_EACH_VEC_ELT_REVERSE (bi->cg_edges, i, cs)
2491 struct cgraph_node *callee = cs->callee;
2493 if (callee)
2495 callee = callee->ultimate_alias_target ();
2496 /* We do not need to bother analyzing calls to unknown functions
2497 unless they may become known during lto/whopr. */
2498 if (!callee->definition && !flag_lto
2499 && !gimple_call_fnspec (cs->call_stmt).known_p ())
2500 continue;
2502 ipa_compute_jump_functions_for_edge (fbi, cs);
2506 /* If STMT looks like a statement loading a value from a member pointer formal
2507 parameter, return that parameter and store the offset of the field to
2508 *OFFSET_P, if it is non-NULL. Otherwise return NULL (but *OFFSET_P still
2509 might be clobbered). If USE_DELTA, then we look for a use of the delta
2510 field rather than the pfn. */
2512 static tree
2513 ipa_get_stmt_member_ptr_load_param (gimple *stmt, bool use_delta,
2514 HOST_WIDE_INT *offset_p)
2516 tree rhs, fld, ptr_field, delta_field;
2517 tree ref_field = NULL_TREE;
2518 tree ref_offset = NULL_TREE;
2520 if (!gimple_assign_single_p (stmt))
2521 return NULL_TREE;
2523 rhs = gimple_assign_rhs1 (stmt);
2524 if (TREE_CODE (rhs) == COMPONENT_REF)
2526 ref_field = TREE_OPERAND (rhs, 1);
2527 rhs = TREE_OPERAND (rhs, 0);
2530 if (TREE_CODE (rhs) == MEM_REF)
2532 ref_offset = TREE_OPERAND (rhs, 1);
2533 if (ref_field && integer_nonzerop (ref_offset))
2534 return NULL_TREE;
2536 else if (!ref_field)
2537 return NULL_TREE;
2539 if (TREE_CODE (rhs) == MEM_REF
2540 && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
2541 && SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (rhs, 0)))
2543 rhs = TREE_OPERAND (rhs, 0);
2544 if (TREE_CODE (SSA_NAME_VAR (rhs)) != PARM_DECL
2545 || !type_like_member_ptr_p (TREE_TYPE (TREE_TYPE (rhs)), &ptr_field,
2546 &delta_field))
2547 return NULL_TREE;
2549 else
2551 if (TREE_CODE (rhs) == MEM_REF
2552 && TREE_CODE (TREE_OPERAND (rhs, 0)) == ADDR_EXPR)
2553 rhs = TREE_OPERAND (TREE_OPERAND (rhs, 0), 0);
2554 if (TREE_CODE (rhs) != PARM_DECL
2555 || !type_like_member_ptr_p (TREE_TYPE (rhs), &ptr_field,
2556 &delta_field))
2557 return NULL_TREE;
2560 if (use_delta)
2561 fld = delta_field;
2562 else
2563 fld = ptr_field;
2565 if (ref_field)
2567 if (ref_field != fld)
2568 return NULL_TREE;
2570 else if (!tree_int_cst_equal (byte_position (fld), ref_offset))
2571 return NULL_TREE;
2573 if (offset_p)
2574 *offset_p = int_bit_position (fld);
2575 return rhs;
2578 /* Returns true iff T is an SSA_NAME defined by a statement. */
2580 static bool
2581 ipa_is_ssa_with_stmt_def (tree t)
2583 if (TREE_CODE (t) == SSA_NAME
2584 && !SSA_NAME_IS_DEFAULT_DEF (t))
2585 return true;
2586 else
2587 return false;
2590 /* Find the indirect call graph edge corresponding to STMT and mark it as a
2591 call to a parameter number PARAM_INDEX. NODE is the caller. Return the
2592 indirect call graph edge.
2593 If POLYMORPHIC is true record is as a destination of polymorphic call. */
2595 static struct cgraph_edge *
2596 ipa_note_param_call (struct cgraph_node *node, int param_index,
2597 gcall *stmt, bool polymorphic)
2599 struct cgraph_edge *cs;
2601 cs = node->get_edge (stmt);
2602 cs->indirect_info->param_index = param_index;
2603 cs->indirect_info->agg_contents = 0;
2604 cs->indirect_info->member_ptr = 0;
2605 cs->indirect_info->guaranteed_unmodified = 0;
2606 ipa_node_params *info = ipa_node_params_sum->get (node);
2607 ipa_set_param_used_by_indirect_call (info, param_index, true);
2608 if (cs->indirect_info->polymorphic || polymorphic)
2609 ipa_set_param_used_by_polymorphic_call (info, param_index, true);
2610 return cs;
2613 /* Analyze the CALL and examine uses of formal parameters of the caller NODE
2614 (described by INFO). PARMS_AINFO is a pointer to a vector containing
2615 intermediate information about each formal parameter. Currently it checks
2616 whether the call calls a pointer that is a formal parameter and if so, the
2617 parameter is marked with the called flag and an indirect call graph edge
2618 describing the call is created. This is very simple for ordinary pointers
2619 represented in SSA but not-so-nice when it comes to member pointers. The
2620 ugly part of this function does nothing more than trying to match the
2621 pattern of such a call. Look up the documentation of macro
2622 TARGET_PTRMEMFUNC_VBIT_LOCATION for details. An example of such a pattern
2623 is the gimple dump below, the call is on the last line:
2625 <bb 2>:
2626 f$__delta_5 = f.__delta;
2627 f$__pfn_24 = f.__pfn;
2630 <bb 2>:
2631 f$__delta_5 = MEM[(struct *)&f];
2632 f$__pfn_24 = MEM[(struct *)&f + 4B];
2634 and a few lines below:
2636 <bb 5>
2637 D.2496_3 = (int) f$__pfn_24;
2638 D.2497_4 = D.2496_3 & 1;
2639 if (D.2497_4 != 0)
2640 goto <bb 3>;
2641 else
2642 goto <bb 4>;
2644 <bb 6>:
2645 D.2500_7 = (unsigned int) f$__delta_5;
2646 D.2501_8 = &S + D.2500_7;
2647 D.2502_9 = (int (*__vtbl_ptr_type) (void) * *) D.2501_8;
2648 D.2503_10 = *D.2502_9;
2649 D.2504_12 = f$__pfn_24 + -1;
2650 D.2505_13 = (unsigned int) D.2504_12;
2651 D.2506_14 = D.2503_10 + D.2505_13;
2652 D.2507_15 = *D.2506_14;
2653 iftmp.11_16 = (String:: *) D.2507_15;
2655 <bb 7>:
2656 # iftmp.11_1 = PHI <iftmp.11_16(3), f$__pfn_24(2)>
2657 D.2500_19 = (unsigned int) f$__delta_5;
2658 D.2508_20 = &S + D.2500_19;
2659 D.2493_21 = iftmp.11_1 (D.2508_20, 4);
2661 Such patterns are results of simple calls to a member pointer:
2663 int doprinting (int (MyString::* f)(int) const)
2665 MyString S ("somestring");
2667 return (S.*f)(4);
2670 Moreover, the function also looks for called pointers loaded from aggregates
2671 passed by value or reference. */
2673 static void
2674 ipa_analyze_indirect_call_uses (struct ipa_func_body_info *fbi, gcall *call,
2675 tree target)
2677 class ipa_node_params *info = fbi->info;
2678 HOST_WIDE_INT offset;
2679 bool by_ref;
2681 if (SSA_NAME_IS_DEFAULT_DEF (target))
2683 tree var = SSA_NAME_VAR (target);
2684 int index = ipa_get_param_decl_index (info, var);
2685 if (index >= 0)
2686 ipa_note_param_call (fbi->node, index, call, false);
2687 return;
2690 int index;
2691 gimple *def = SSA_NAME_DEF_STMT (target);
2692 bool guaranteed_unmodified;
2693 if (gimple_assign_single_p (def)
2694 && ipa_load_from_parm_agg (fbi, info->descriptors, def,
2695 gimple_assign_rhs1 (def), &index, &offset,
2696 NULL, &by_ref, &guaranteed_unmodified))
2698 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
2699 call, false);
2700 cs->indirect_info->offset = offset;
2701 cs->indirect_info->agg_contents = 1;
2702 cs->indirect_info->by_ref = by_ref;
2703 cs->indirect_info->guaranteed_unmodified = guaranteed_unmodified;
2704 return;
2707 /* Now we need to try to match the complex pattern of calling a member
2708 pointer. */
2709 if (gimple_code (def) != GIMPLE_PHI
2710 || gimple_phi_num_args (def) != 2
2711 || !POINTER_TYPE_P (TREE_TYPE (target))
2712 || TREE_CODE (TREE_TYPE (TREE_TYPE (target))) != METHOD_TYPE)
2713 return;
2715 /* First, we need to check whether one of these is a load from a member
2716 pointer that is a parameter to this function. */
2717 tree n1 = PHI_ARG_DEF (def, 0);
2718 tree n2 = PHI_ARG_DEF (def, 1);
2719 if (!ipa_is_ssa_with_stmt_def (n1) || !ipa_is_ssa_with_stmt_def (n2))
2720 return;
2721 gimple *d1 = SSA_NAME_DEF_STMT (n1);
2722 gimple *d2 = SSA_NAME_DEF_STMT (n2);
2724 tree rec;
2725 basic_block bb, virt_bb;
2726 basic_block join = gimple_bb (def);
2727 if ((rec = ipa_get_stmt_member_ptr_load_param (d1, false, &offset)))
2729 if (ipa_get_stmt_member_ptr_load_param (d2, false, NULL))
2730 return;
2732 bb = EDGE_PRED (join, 0)->src;
2733 virt_bb = gimple_bb (d2);
2735 else if ((rec = ipa_get_stmt_member_ptr_load_param (d2, false, &offset)))
2737 bb = EDGE_PRED (join, 1)->src;
2738 virt_bb = gimple_bb (d1);
2740 else
2741 return;
2743 /* Second, we need to check that the basic blocks are laid out in the way
2744 corresponding to the pattern. */
2746 if (!single_pred_p (virt_bb) || !single_succ_p (virt_bb)
2747 || single_succ (virt_bb) != join)
2748 return;
2751 if (single_pred (virt_bb) != bb)
2753 /* In cases when the distinction between a normal and a virtual
2754 function is encoded in the delta field, the load of the
2755 actual non-virtual function pointer can be in its own BB. */
2757 if (!single_pred_p (bb) || !single_succ_p (bb))
2758 return;
2759 bb = single_pred (bb);
2760 if (bb != single_pred (virt_bb))
2761 return;
2764 /* Third, let's see that the branching is done depending on the least
2765 significant bit of the pfn. */
2767 gcond *branch = safe_dyn_cast <gcond *> (*gsi_last_bb (bb));
2768 if (!branch)
2769 return;
2771 if ((gimple_cond_code (branch) != NE_EXPR
2772 && gimple_cond_code (branch) != EQ_EXPR)
2773 || !integer_zerop (gimple_cond_rhs (branch)))
2774 return;
2776 tree cond = gimple_cond_lhs (branch);
2777 if (!ipa_is_ssa_with_stmt_def (cond))
2778 return;
2780 def = SSA_NAME_DEF_STMT (cond);
2781 if (!is_gimple_assign (def)
2782 || gimple_assign_rhs_code (def) != BIT_AND_EXPR
2783 || !integer_onep (gimple_assign_rhs2 (def)))
2784 return;
2786 cond = gimple_assign_rhs1 (def);
2787 if (!ipa_is_ssa_with_stmt_def (cond))
2788 return;
2790 def = SSA_NAME_DEF_STMT (cond);
2792 if (is_gimple_assign (def)
2793 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
2795 cond = gimple_assign_rhs1 (def);
2796 if (!ipa_is_ssa_with_stmt_def (cond))
2797 return;
2798 def = SSA_NAME_DEF_STMT (cond);
2801 tree rec2;
2802 rec2 = ipa_get_stmt_member_ptr_load_param (def,
2803 (TARGET_PTRMEMFUNC_VBIT_LOCATION
2804 == ptrmemfunc_vbit_in_delta),
2805 NULL);
2806 if (rec != rec2)
2807 return;
2809 if (TREE_CODE (rec) == SSA_NAME)
2811 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (rec));
2812 if (index < 0
2813 || !parm_ref_data_preserved_p (fbi, index, call,
2814 gimple_assign_rhs1 (def)))
2815 return;
2816 by_ref = true;
2818 else
2820 index = ipa_get_param_decl_index (info, rec);
2821 if (index < 0
2822 || !parm_preserved_before_stmt_p (fbi, index, call, rec))
2823 return;
2824 by_ref = false;
2827 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
2828 call, false);
2829 cs->indirect_info->offset = offset;
2830 cs->indirect_info->agg_contents = 1;
2831 cs->indirect_info->member_ptr = 1;
2832 cs->indirect_info->by_ref = by_ref;
2833 cs->indirect_info->guaranteed_unmodified = 1;
2835 return;
2838 /* Analyze a CALL to an OBJ_TYPE_REF which is passed in TARGET and if the
2839 object referenced in the expression is a formal parameter of the caller
2840 FBI->node (described by FBI->info), create a call note for the
2841 statement. */
2843 static void
2844 ipa_analyze_virtual_call_uses (struct ipa_func_body_info *fbi,
2845 gcall *call, tree target)
2847 tree obj = OBJ_TYPE_REF_OBJECT (target);
2848 int index;
2849 HOST_WIDE_INT anc_offset;
2851 if (!flag_devirtualize)
2852 return;
2854 if (TREE_CODE (obj) != SSA_NAME)
2855 return;
2857 class ipa_node_params *info = fbi->info;
2858 if (SSA_NAME_IS_DEFAULT_DEF (obj))
2860 if (TREE_CODE (SSA_NAME_VAR (obj)) != PARM_DECL)
2861 return;
2863 anc_offset = 0;
2864 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (obj));
2865 gcc_assert (index >= 0);
2866 if (detect_type_change_ssa (fbi, obj, obj_type_ref_class (target),
2867 call))
2868 return;
2870 else
2872 gimple *stmt = SSA_NAME_DEF_STMT (obj);
2873 tree expr;
2875 expr = get_ancestor_addr_info (stmt, &obj, &anc_offset);
2876 if (!expr)
2877 return;
2878 index = ipa_get_param_decl_index (info,
2879 SSA_NAME_VAR (TREE_OPERAND (expr, 0)));
2880 gcc_assert (index >= 0);
2881 if (detect_type_change (fbi, obj, expr, obj_type_ref_class (target),
2882 call, anc_offset))
2883 return;
2886 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
2887 call, true);
2888 class cgraph_indirect_call_info *ii = cs->indirect_info;
2889 ii->offset = anc_offset;
2890 ii->otr_token = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target));
2891 ii->otr_type = obj_type_ref_class (target);
2892 ii->polymorphic = 1;
2895 /* Analyze a call statement CALL whether and how it utilizes formal parameters
2896 of the caller (described by INFO). PARMS_AINFO is a pointer to a vector
2897 containing intermediate information about each formal parameter. */
2899 static void
2900 ipa_analyze_call_uses (struct ipa_func_body_info *fbi, gcall *call)
2902 tree target = gimple_call_fn (call);
2904 if (!target
2905 || (TREE_CODE (target) != SSA_NAME
2906 && !virtual_method_call_p (target)))
2907 return;
2909 struct cgraph_edge *cs = fbi->node->get_edge (call);
2910 /* If we previously turned the call into a direct call, there is
2911 no need to analyze. */
2912 if (cs && !cs->indirect_unknown_callee)
2913 return;
2915 if (cs->indirect_info->polymorphic && flag_devirtualize)
2917 tree instance;
2918 tree target = gimple_call_fn (call);
2919 ipa_polymorphic_call_context context (current_function_decl,
2920 target, call, &instance);
2922 gcc_checking_assert (cs->indirect_info->otr_type
2923 == obj_type_ref_class (target));
2924 gcc_checking_assert (cs->indirect_info->otr_token
2925 == tree_to_shwi (OBJ_TYPE_REF_TOKEN (target)));
2927 cs->indirect_info->vptr_changed
2928 = !context.get_dynamic_type (instance,
2929 OBJ_TYPE_REF_OBJECT (target),
2930 obj_type_ref_class (target), call,
2931 &fbi->aa_walk_budget);
2932 cs->indirect_info->context = context;
2935 if (TREE_CODE (target) == SSA_NAME)
2936 ipa_analyze_indirect_call_uses (fbi, call, target);
2937 else if (virtual_method_call_p (target))
2938 ipa_analyze_virtual_call_uses (fbi, call, target);
2942 /* Analyze the call statement STMT with respect to formal parameters (described
2943 in INFO) of caller given by FBI->NODE. Currently it only checks whether
2944 formal parameters are called. */
2946 static void
2947 ipa_analyze_stmt_uses (struct ipa_func_body_info *fbi, gimple *stmt)
2949 if (is_gimple_call (stmt))
2950 ipa_analyze_call_uses (fbi, as_a <gcall *> (stmt));
2953 /* Callback of walk_stmt_load_store_addr_ops for the visit_load.
2954 If OP is a parameter declaration, mark it as used in the info structure
2955 passed in DATA. */
2957 static bool
2958 visit_ref_for_mod_analysis (gimple *, tree op, tree, void *data)
2960 class ipa_node_params *info = (class ipa_node_params *) data;
2962 op = get_base_address (op);
2963 if (op
2964 && TREE_CODE (op) == PARM_DECL)
2966 int index = ipa_get_param_decl_index (info, op);
2967 gcc_assert (index >= 0);
2968 ipa_set_param_used (info, index, true);
2971 return false;
2974 /* Scan the statements in BB and inspect the uses of formal parameters. Store
2975 the findings in various structures of the associated ipa_node_params
2976 structure, such as parameter flags, notes etc. FBI holds various data about
2977 the function being analyzed. */
2979 static void
2980 ipa_analyze_params_uses_in_bb (struct ipa_func_body_info *fbi, basic_block bb)
2982 gimple_stmt_iterator gsi;
2983 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2985 gimple *stmt = gsi_stmt (gsi);
2987 if (is_gimple_debug (stmt))
2988 continue;
2990 ipa_analyze_stmt_uses (fbi, stmt);
2991 walk_stmt_load_store_addr_ops (stmt, fbi->info,
2992 visit_ref_for_mod_analysis,
2993 visit_ref_for_mod_analysis,
2994 visit_ref_for_mod_analysis);
2996 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2997 walk_stmt_load_store_addr_ops (gsi_stmt (gsi), fbi->info,
2998 visit_ref_for_mod_analysis,
2999 visit_ref_for_mod_analysis,
3000 visit_ref_for_mod_analysis);
3003 /* Return true EXPR is a load from a dereference of SSA_NAME NAME. */
3005 static bool
3006 load_from_dereferenced_name (tree expr, tree name)
3008 tree base = get_base_address (expr);
3009 return (TREE_CODE (base) == MEM_REF
3010 && TREE_OPERAND (base, 0) == name);
3013 /* Calculate controlled uses of parameters of NODE. */
3015 static void
3016 ipa_analyze_controlled_uses (struct cgraph_node *node)
3018 ipa_node_params *info = ipa_node_params_sum->get (node);
3020 for (int i = 0; i < ipa_get_param_count (info); i++)
3022 tree parm = ipa_get_param (info, i);
3023 int call_uses = 0;
3024 bool load_dereferenced = false;
3026 /* For SSA regs see if parameter is used. For non-SSA we compute
3027 the flag during modification analysis. */
3028 if (is_gimple_reg (parm))
3030 tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl),
3031 parm);
3032 if (ddef && !has_zero_uses (ddef))
3034 imm_use_iterator imm_iter;
3035 gimple *stmt;
3037 ipa_set_param_used (info, i, true);
3038 FOR_EACH_IMM_USE_STMT (stmt, imm_iter, ddef)
3040 if (is_gimple_debug (stmt))
3041 continue;
3043 int all_stmt_uses = 0;
3044 use_operand_p use_p;
3045 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
3046 all_stmt_uses++;
3048 if (is_gimple_call (stmt))
3050 if (gimple_call_internal_p (stmt))
3052 call_uses = IPA_UNDESCRIBED_USE;
3053 break;
3055 int recognized_stmt_uses;
3056 if (gimple_call_fn (stmt) == ddef)
3057 recognized_stmt_uses = 1;
3058 else
3059 recognized_stmt_uses = 0;
3060 unsigned arg_count = gimple_call_num_args (stmt);
3061 for (unsigned i = 0; i < arg_count; i++)
3063 tree arg = gimple_call_arg (stmt, i);
3064 if (arg == ddef)
3065 recognized_stmt_uses++;
3066 else if (load_from_dereferenced_name (arg, ddef))
3068 load_dereferenced = true;
3069 recognized_stmt_uses++;
3073 if (recognized_stmt_uses != all_stmt_uses)
3075 call_uses = IPA_UNDESCRIBED_USE;
3076 break;
3078 if (call_uses >= 0)
3079 call_uses += all_stmt_uses;
3081 else if (gimple_assign_single_p (stmt))
3083 tree rhs = gimple_assign_rhs1 (stmt);
3084 if (all_stmt_uses != 1
3085 || !load_from_dereferenced_name (rhs, ddef))
3087 call_uses = IPA_UNDESCRIBED_USE;
3088 break;
3090 load_dereferenced = true;
3092 else
3094 call_uses = IPA_UNDESCRIBED_USE;
3095 break;
3099 else
3100 call_uses = 0;
3102 else
3103 call_uses = IPA_UNDESCRIBED_USE;
3104 ipa_set_controlled_uses (info, i, call_uses);
3105 ipa_set_param_load_dereferenced (info, i, load_dereferenced);
3109 /* Free stuff in BI. */
3111 static void
3112 free_ipa_bb_info (struct ipa_bb_info *bi)
3114 bi->cg_edges.release ();
3115 bi->param_aa_statuses.release ();
3118 /* Dominator walker driving the analysis. */
3120 class analysis_dom_walker : public dom_walker
3122 public:
3123 analysis_dom_walker (struct ipa_func_body_info *fbi)
3124 : dom_walker (CDI_DOMINATORS), m_fbi (fbi) {}
3126 edge before_dom_children (basic_block) final override;
3128 private:
3129 struct ipa_func_body_info *m_fbi;
3132 edge
3133 analysis_dom_walker::before_dom_children (basic_block bb)
3135 ipa_analyze_params_uses_in_bb (m_fbi, bb);
3136 ipa_compute_jump_functions_for_bb (m_fbi, bb);
3137 return NULL;
3140 /* Release body info FBI. */
3142 void
3143 ipa_release_body_info (struct ipa_func_body_info *fbi)
3145 int i;
3146 struct ipa_bb_info *bi;
3148 FOR_EACH_VEC_ELT (fbi->bb_infos, i, bi)
3149 free_ipa_bb_info (bi);
3150 fbi->bb_infos.release ();
3153 /* Initialize the array describing properties of formal parameters
3154 of NODE, analyze their uses and compute jump functions associated
3155 with actual arguments of calls from within NODE. */
3157 void
3158 ipa_analyze_node (struct cgraph_node *node)
3160 struct ipa_func_body_info fbi;
3161 class ipa_node_params *info;
3163 ipa_check_create_node_params ();
3164 ipa_check_create_edge_args ();
3165 info = ipa_node_params_sum->get_create (node);
3167 if (info->analysis_done)
3168 return;
3169 info->analysis_done = 1;
3171 if (ipa_func_spec_opts_forbid_analysis_p (node)
3172 || (count_formal_params (node->decl)
3173 >= (1 << IPA_PROP_ARG_INDEX_LIMIT_BITS)))
3175 gcc_assert (!ipa_get_param_count (info));
3176 return;
3179 struct function *func = DECL_STRUCT_FUNCTION (node->decl);
3180 push_cfun (func);
3181 calculate_dominance_info (CDI_DOMINATORS);
3182 ipa_initialize_node_params (node);
3183 ipa_analyze_controlled_uses (node);
3185 fbi.node = node;
3186 fbi.info = info;
3187 fbi.bb_infos = vNULL;
3188 fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
3189 fbi.param_count = ipa_get_param_count (info);
3190 fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps);
3192 for (struct cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
3194 ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
3195 bi->cg_edges.safe_push (cs);
3198 for (struct cgraph_edge *cs = node->indirect_calls; cs; cs = cs->next_callee)
3200 ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
3201 bi->cg_edges.safe_push (cs);
3204 enable_ranger (cfun, false);
3205 analysis_dom_walker (&fbi).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
3206 disable_ranger (cfun);
3208 ipa_release_body_info (&fbi);
3209 free_dominance_info (CDI_DOMINATORS);
3210 pop_cfun ();
3213 /* Update the jump functions associated with call graph edge E when the call
3214 graph edge CS is being inlined, assuming that E->caller is already (possibly
3215 indirectly) inlined into CS->callee and that E has not been inlined. */
3217 static void
3218 update_jump_functions_after_inlining (struct cgraph_edge *cs,
3219 struct cgraph_edge *e)
3221 ipa_edge_args *top = ipa_edge_args_sum->get (cs);
3222 ipa_edge_args *args = ipa_edge_args_sum->get (e);
3223 if (!args)
3224 return;
3225 int count = ipa_get_cs_argument_count (args);
3226 int i;
3228 for (i = 0; i < count; i++)
3230 struct ipa_jump_func *dst = ipa_get_ith_jump_func (args, i);
3231 class ipa_polymorphic_call_context *dst_ctx
3232 = ipa_get_ith_polymorhic_call_context (args, i);
3234 if (dst->agg.items)
3236 struct ipa_agg_jf_item *item;
3237 int j;
3239 FOR_EACH_VEC_ELT (*dst->agg.items, j, item)
3241 int dst_fid;
3242 struct ipa_jump_func *src;
3244 if (item->jftype != IPA_JF_PASS_THROUGH
3245 && item->jftype != IPA_JF_LOAD_AGG)
3246 continue;
3248 dst_fid = item->value.pass_through.formal_id;
3249 if (!top || dst_fid >= ipa_get_cs_argument_count (top))
3251 item->jftype = IPA_JF_UNKNOWN;
3252 continue;
3255 item->value.pass_through.formal_id = -1;
3256 src = ipa_get_ith_jump_func (top, dst_fid);
3257 if (src->type == IPA_JF_CONST)
3259 if (item->jftype == IPA_JF_PASS_THROUGH
3260 && item->value.pass_through.operation == NOP_EXPR)
3262 item->jftype = IPA_JF_CONST;
3263 item->value.constant = src->value.constant.value;
3264 continue;
3267 else if (src->type == IPA_JF_PASS_THROUGH
3268 && src->value.pass_through.operation == NOP_EXPR)
3270 if (item->jftype == IPA_JF_PASS_THROUGH
3271 || !item->value.load_agg.by_ref
3272 || src->value.pass_through.agg_preserved)
3273 item->value.pass_through.formal_id
3274 = src->value.pass_through.formal_id;
3276 else if (src->type == IPA_JF_ANCESTOR)
3278 if (item->jftype == IPA_JF_PASS_THROUGH)
3280 if (!src->value.ancestor.offset)
3281 item->value.pass_through.formal_id
3282 = src->value.ancestor.formal_id;
3284 else if (src->value.ancestor.agg_preserved)
3286 gcc_checking_assert (item->value.load_agg.by_ref);
3288 item->value.pass_through.formal_id
3289 = src->value.ancestor.formal_id;
3290 item->value.load_agg.offset
3291 += src->value.ancestor.offset;
3295 if (item->value.pass_through.formal_id < 0)
3296 item->jftype = IPA_JF_UNKNOWN;
3300 if (!top)
3302 ipa_set_jf_unknown (dst);
3303 continue;
3306 if (dst->type == IPA_JF_ANCESTOR)
3308 struct ipa_jump_func *src;
3309 int dst_fid = dst->value.ancestor.formal_id;
3310 class ipa_polymorphic_call_context *src_ctx
3311 = ipa_get_ith_polymorhic_call_context (top, dst_fid);
3313 /* Variable number of arguments can cause havoc if we try to access
3314 one that does not exist in the inlined edge. So make sure we
3315 don't. */
3316 if (dst_fid >= ipa_get_cs_argument_count (top))
3318 ipa_set_jf_unknown (dst);
3319 continue;
3322 src = ipa_get_ith_jump_func (top, dst_fid);
3324 if (src_ctx && !src_ctx->useless_p ())
3326 class ipa_polymorphic_call_context ctx = *src_ctx;
3328 /* TODO: Make type preserved safe WRT contexts. */
3329 if (!ipa_get_jf_ancestor_type_preserved (dst))
3330 ctx.possible_dynamic_type_change (e->in_polymorphic_cdtor);
3331 ctx.offset_by (dst->value.ancestor.offset);
3332 if (!ctx.useless_p ())
3334 if (!dst_ctx)
3336 vec_safe_grow_cleared (args->polymorphic_call_contexts,
3337 count, true);
3338 dst_ctx = ipa_get_ith_polymorhic_call_context (args, i);
3341 dst_ctx->combine_with (ctx);
3345 /* Parameter and argument in ancestor jump function must be pointer
3346 type, which means access to aggregate must be by-reference. */
3347 gcc_assert (!src->agg.items || src->agg.by_ref);
3349 if (src->agg.items && dst->value.ancestor.agg_preserved)
3351 struct ipa_agg_jf_item *item;
3352 int j;
3354 /* Currently we do not produce clobber aggregate jump functions,
3355 replace with merging when we do. */
3356 gcc_assert (!dst->agg.items);
3358 dst->agg.items = vec_safe_copy (src->agg.items);
3359 dst->agg.by_ref = src->agg.by_ref;
3360 FOR_EACH_VEC_SAFE_ELT (dst->agg.items, j, item)
3361 item->offset -= dst->value.ancestor.offset;
3364 if (src->type == IPA_JF_PASS_THROUGH
3365 && src->value.pass_through.operation == NOP_EXPR)
3367 dst->value.ancestor.formal_id = src->value.pass_through.formal_id;
3368 dst->value.ancestor.agg_preserved &=
3369 src->value.pass_through.agg_preserved;
3371 else if (src->type == IPA_JF_ANCESTOR)
3373 dst->value.ancestor.formal_id = src->value.ancestor.formal_id;
3374 dst->value.ancestor.offset += src->value.ancestor.offset;
3375 dst->value.ancestor.agg_preserved &=
3376 src->value.ancestor.agg_preserved;
3377 dst->value.ancestor.keep_null |= src->value.ancestor.keep_null;
3379 else
3380 ipa_set_jf_unknown (dst);
3382 else if (dst->type == IPA_JF_PASS_THROUGH)
3384 struct ipa_jump_func *src;
3385 /* We must check range due to calls with variable number of arguments
3386 and we cannot combine jump functions with operations. */
3387 if (dst->value.pass_through.operation == NOP_EXPR
3388 && (top && dst->value.pass_through.formal_id
3389 < ipa_get_cs_argument_count (top)))
3391 int dst_fid = dst->value.pass_through.formal_id;
3392 src = ipa_get_ith_jump_func (top, dst_fid);
3393 bool dst_agg_p = ipa_get_jf_pass_through_agg_preserved (dst);
3394 class ipa_polymorphic_call_context *src_ctx
3395 = ipa_get_ith_polymorhic_call_context (top, dst_fid);
3397 if (src_ctx && !src_ctx->useless_p ())
3399 class ipa_polymorphic_call_context ctx = *src_ctx;
3401 /* TODO: Make type preserved safe WRT contexts. */
3402 if (!ipa_get_jf_pass_through_type_preserved (dst))
3403 ctx.possible_dynamic_type_change (e->in_polymorphic_cdtor);
3404 if (!ctx.useless_p ())
3406 if (!dst_ctx)
3408 vec_safe_grow_cleared (args->polymorphic_call_contexts,
3409 count, true);
3410 dst_ctx = ipa_get_ith_polymorhic_call_context (args, i);
3412 dst_ctx->combine_with (ctx);
3415 switch (src->type)
3417 case IPA_JF_UNKNOWN:
3418 ipa_set_jf_unknown (dst);
3419 break;
3420 case IPA_JF_CONST:
3422 bool rd = ipa_get_jf_pass_through_refdesc_decremented (dst);
3423 ipa_set_jf_cst_copy (dst, src);
3424 if (rd)
3425 ipa_zap_jf_refdesc (dst);
3428 break;
3430 case IPA_JF_PASS_THROUGH:
3432 int formal_id = ipa_get_jf_pass_through_formal_id (src);
3433 enum tree_code operation;
3434 operation = ipa_get_jf_pass_through_operation (src);
3436 if (operation == NOP_EXPR)
3438 bool agg_p;
3439 agg_p = dst_agg_p
3440 && ipa_get_jf_pass_through_agg_preserved (src);
3441 ipa_set_jf_simple_pass_through (dst, formal_id, agg_p);
3443 else if (TREE_CODE_CLASS (operation) == tcc_unary)
3444 ipa_set_jf_unary_pass_through (dst, formal_id, operation);
3445 else
3447 tree operand = ipa_get_jf_pass_through_operand (src);
3448 ipa_set_jf_arith_pass_through (dst, formal_id, operand,
3449 operation);
3451 break;
3453 case IPA_JF_ANCESTOR:
3455 bool agg_p;
3456 agg_p = dst_agg_p
3457 && ipa_get_jf_ancestor_agg_preserved (src);
3458 ipa_set_ancestor_jf (dst,
3459 ipa_get_jf_ancestor_offset (src),
3460 ipa_get_jf_ancestor_formal_id (src),
3461 agg_p,
3462 ipa_get_jf_ancestor_keep_null (src));
3463 break;
3465 default:
3466 gcc_unreachable ();
3469 if (src->agg.items
3470 && (dst_agg_p || !src->agg.by_ref))
3472 /* Currently we do not produce clobber aggregate jump
3473 functions, replace with merging when we do. */
3474 gcc_assert (!dst->agg.items);
3476 dst->agg.by_ref = src->agg.by_ref;
3477 dst->agg.items = vec_safe_copy (src->agg.items);
3480 else
3481 ipa_set_jf_unknown (dst);
3486 /* If TARGET is an addr_expr of a function declaration, make it the
3487 (SPECULATIVE)destination of an indirect edge IE and return the edge.
3488 Otherwise, return NULL. */
3490 struct cgraph_edge *
3491 ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
3492 bool speculative)
3494 struct cgraph_node *callee;
3495 bool unreachable = false;
3497 if (TREE_CODE (target) == ADDR_EXPR)
3498 target = TREE_OPERAND (target, 0);
3499 if (TREE_CODE (target) != FUNCTION_DECL)
3501 target = canonicalize_constructor_val (target, NULL);
3502 if (!target || TREE_CODE (target) != FUNCTION_DECL)
3504 /* Member pointer call that goes through a VMT lookup. */
3505 if (ie->indirect_info->member_ptr
3506 /* Or if target is not an invariant expression and we do not
3507 know if it will evaulate to function at runtime.
3508 This can happen when folding through &VAR, where &VAR
3509 is IP invariant, but VAR itself is not.
3511 TODO: Revisit this when GCC 5 is branched. It seems that
3512 member_ptr check is not needed and that we may try to fold
3513 the expression and see if VAR is readonly. */
3514 || !is_gimple_ip_invariant (target))
3516 if (dump_enabled_p ())
3518 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
3519 "discovered direct call non-invariant %s\n",
3520 ie->caller->dump_name ());
3522 return NULL;
3526 if (dump_enabled_p ())
3528 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
3529 "discovered direct call to non-function in %s, "
3530 "making it __builtin_unreachable\n",
3531 ie->caller->dump_name ());
3534 target = builtin_decl_unreachable ();
3535 callee = cgraph_node::get_create (target);
3536 unreachable = true;
3538 else
3539 callee = cgraph_node::get (target);
3541 else
3542 callee = cgraph_node::get (target);
3544 /* Because may-edges are not explicitely represented and vtable may be external,
3545 we may create the first reference to the object in the unit. */
3546 if (!callee || callee->inlined_to)
3549 /* We are better to ensure we can refer to it.
3550 In the case of static functions we are out of luck, since we already
3551 removed its body. In the case of public functions we may or may
3552 not introduce the reference. */
3553 if (!canonicalize_constructor_val (target, NULL)
3554 || !TREE_PUBLIC (target))
3556 if (dump_file)
3557 fprintf (dump_file, "ipa-prop: Discovered call to a known target "
3558 "(%s -> %s) but cannot refer to it. Giving up.\n",
3559 ie->caller->dump_name (),
3560 ie->callee->dump_name ());
3561 return NULL;
3563 callee = cgraph_node::get_create (target);
3566 /* If the edge is already speculated. */
3567 if (speculative && ie->speculative)
3569 if (dump_file)
3571 cgraph_edge *e2 = ie->speculative_call_for_target (callee);
3572 if (!e2)
3574 if (dump_file)
3575 fprintf (dump_file, "ipa-prop: Discovered call to a "
3576 "speculative target (%s -> %s) but the call is "
3577 "already speculated to different target. "
3578 "Giving up.\n",
3579 ie->caller->dump_name (), callee->dump_name ());
3581 else
3583 if (dump_file)
3584 fprintf (dump_file,
3585 "ipa-prop: Discovered call to a speculative target "
3586 "(%s -> %s) this agree with previous speculation.\n",
3587 ie->caller->dump_name (), callee->dump_name ());
3590 return NULL;
3593 if (!dbg_cnt (devirt))
3594 return NULL;
3596 ipa_check_create_node_params ();
3598 /* We cannot make edges to inline clones. It is bug that someone removed
3599 the cgraph node too early. */
3600 gcc_assert (!callee->inlined_to);
3602 if (dump_file && !unreachable)
3604 fprintf (dump_file, "ipa-prop: Discovered %s call to a %s target "
3605 "(%s -> %s), for stmt ",
3606 ie->indirect_info->polymorphic ? "a virtual" : "an indirect",
3607 speculative ? "speculative" : "known",
3608 ie->caller->dump_name (),
3609 callee->dump_name ());
3610 if (ie->call_stmt)
3611 print_gimple_stmt (dump_file, ie->call_stmt, 2, TDF_SLIM);
3612 else
3613 fprintf (dump_file, "with uid %i\n", ie->lto_stmt_uid);
3615 if (dump_enabled_p ())
3617 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
3618 "converting indirect call in %s to direct call to %s\n",
3619 ie->caller->dump_name (), callee->dump_name ());
3621 if (!speculative)
3623 struct cgraph_edge *orig = ie;
3624 ie = cgraph_edge::make_direct (ie, callee);
3625 /* If we resolved speculative edge the cost is already up to date
3626 for direct call (adjusted by inline_edge_duplication_hook). */
3627 if (ie == orig)
3629 ipa_call_summary *es = ipa_call_summaries->get (ie);
3630 es->call_stmt_size -= (eni_size_weights.indirect_call_cost
3631 - eni_size_weights.call_cost);
3632 es->call_stmt_time -= (eni_time_weights.indirect_call_cost
3633 - eni_time_weights.call_cost);
3636 else
3638 if (!callee->can_be_discarded_p ())
3640 cgraph_node *alias;
3641 alias = dyn_cast<cgraph_node *> (callee->noninterposable_alias ());
3642 if (alias)
3643 callee = alias;
3645 /* make_speculative will update ie's cost to direct call cost. */
3646 ie = ie->make_speculative
3647 (callee, ie->count.apply_scale (8, 10));
3650 return ie;
3653 /* Attempt to locate an interprocedural constant at a given REQ_OFFSET in
3654 CONSTRUCTOR and return it. Return NULL if the search fails for some
3655 reason. */
3657 static tree
3658 find_constructor_constant_at_offset (tree constructor, HOST_WIDE_INT req_offset)
3660 tree type = TREE_TYPE (constructor);
3661 if (TREE_CODE (type) != ARRAY_TYPE
3662 && TREE_CODE (type) != RECORD_TYPE)
3663 return NULL;
3665 unsigned ix;
3666 tree index, val;
3667 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (constructor), ix, index, val)
3669 HOST_WIDE_INT elt_offset;
3670 if (TREE_CODE (type) == ARRAY_TYPE)
3672 offset_int off;
3673 tree unit_size = TYPE_SIZE_UNIT (TREE_TYPE (type));
3674 gcc_assert (TREE_CODE (unit_size) == INTEGER_CST);
3676 if (index)
3678 if (TREE_CODE (index) == RANGE_EXPR)
3679 off = wi::to_offset (TREE_OPERAND (index, 0));
3680 else
3681 off = wi::to_offset (index);
3682 if (TYPE_DOMAIN (type) && TYPE_MIN_VALUE (TYPE_DOMAIN (type)))
3684 tree low_bound = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
3685 gcc_assert (TREE_CODE (unit_size) == INTEGER_CST);
3686 off = wi::sext (off - wi::to_offset (low_bound),
3687 TYPE_PRECISION (TREE_TYPE (index)));
3689 off *= wi::to_offset (unit_size);
3690 /* ??? Handle more than just the first index of a
3691 RANGE_EXPR. */
3693 else
3694 off = wi::to_offset (unit_size) * ix;
3696 off = wi::lshift (off, LOG2_BITS_PER_UNIT);
3697 if (!wi::fits_shwi_p (off) || wi::neg_p (off))
3698 continue;
3699 elt_offset = off.to_shwi ();
3701 else if (TREE_CODE (type) == RECORD_TYPE)
3703 gcc_checking_assert (index && TREE_CODE (index) == FIELD_DECL);
3704 if (DECL_BIT_FIELD (index))
3705 continue;
3706 elt_offset = int_bit_position (index);
3708 else
3709 gcc_unreachable ();
3711 if (elt_offset > req_offset)
3712 return NULL;
3714 if (TREE_CODE (val) == CONSTRUCTOR)
3715 return find_constructor_constant_at_offset (val,
3716 req_offset - elt_offset);
3718 if (elt_offset == req_offset
3719 && is_gimple_reg_type (TREE_TYPE (val))
3720 && is_gimple_ip_invariant (val))
3721 return val;
3723 return NULL;
3726 /* Check whether SCALAR could be used to look up an aggregate interprocedural
3727 invariant from a static constructor and if so, return it. Otherwise return
3728 NULL. */
3730 tree
3731 ipa_find_agg_cst_from_init (tree scalar, HOST_WIDE_INT offset, bool by_ref)
3733 if (by_ref)
3735 if (TREE_CODE (scalar) != ADDR_EXPR)
3736 return NULL;
3737 scalar = TREE_OPERAND (scalar, 0);
3740 if (!VAR_P (scalar)
3741 || !is_global_var (scalar)
3742 || !TREE_READONLY (scalar)
3743 || !DECL_INITIAL (scalar)
3744 || TREE_CODE (DECL_INITIAL (scalar)) != CONSTRUCTOR)
3745 return NULL;
3747 return find_constructor_constant_at_offset (DECL_INITIAL (scalar), offset);
3750 /* Retrieve value from AGG_JFUNC for the given OFFSET or return NULL if there
3751 is none. BY_REF specifies whether the value has to be passed by reference
3752 or by value. */
3754 static tree
3755 ipa_find_agg_cst_from_jfunc_items (struct ipa_agg_jump_function *agg_jfunc,
3756 ipa_node_params *src_info,
3757 cgraph_node *src_node,
3758 HOST_WIDE_INT offset, bool by_ref)
3760 if (by_ref != agg_jfunc->by_ref)
3761 return NULL_TREE;
3763 for (const ipa_agg_jf_item &item : agg_jfunc->items)
3764 if (item.offset == offset)
3765 return ipa_agg_value_from_jfunc (src_info, src_node, &item);
3767 return NULL_TREE;
3770 /* Remove a reference to SYMBOL from the list of references of a node given by
3771 reference description RDESC. Return true if the reference has been
3772 successfully found and removed. */
3774 static bool
3775 remove_described_reference (symtab_node *symbol, struct ipa_cst_ref_desc *rdesc)
3777 struct ipa_ref *to_del;
3778 struct cgraph_edge *origin;
3780 origin = rdesc->cs;
3781 if (!origin)
3782 return false;
3783 to_del = origin->caller->find_reference (symbol, origin->call_stmt,
3784 origin->lto_stmt_uid, IPA_REF_ADDR);
3785 if (!to_del)
3786 return false;
3788 to_del->remove_reference ();
3789 if (dump_file)
3790 fprintf (dump_file, "ipa-prop: Removed a reference from %s to %s.\n",
3791 origin->caller->dump_name (), symbol->dump_name ());
3792 return true;
3795 /* If JFUNC has a reference description with refcount different from
3796 IPA_UNDESCRIBED_USE, return the reference description, otherwise return
3797 NULL. JFUNC must be a constant jump function. */
3799 static struct ipa_cst_ref_desc *
3800 jfunc_rdesc_usable (struct ipa_jump_func *jfunc)
3802 struct ipa_cst_ref_desc *rdesc = ipa_get_jf_constant_rdesc (jfunc);
3803 if (rdesc && rdesc->refcount != IPA_UNDESCRIBED_USE)
3804 return rdesc;
3805 else
3806 return NULL;
3809 /* If the value of constant jump function JFUNC is an address of a function
3810 declaration, return the associated call graph node. Otherwise return
3811 NULL. */
3813 static symtab_node *
3814 symtab_node_for_jfunc (struct ipa_jump_func *jfunc)
3816 gcc_checking_assert (jfunc->type == IPA_JF_CONST);
3817 tree cst = ipa_get_jf_constant (jfunc);
3818 if (TREE_CODE (cst) != ADDR_EXPR
3819 || (TREE_CODE (TREE_OPERAND (cst, 0)) != FUNCTION_DECL
3820 && TREE_CODE (TREE_OPERAND (cst, 0)) != VAR_DECL))
3821 return NULL;
3823 return symtab_node::get (TREE_OPERAND (cst, 0));
3827 /* If JFUNC is a constant jump function with a usable rdesc, decrement its
3828 refcount and if it hits zero, remove reference to SYMBOL from the caller of
3829 the edge specified in the rdesc. Return false if either the symbol or the
3830 reference could not be found, otherwise return true. */
3832 static bool
3833 try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc)
3835 struct ipa_cst_ref_desc *rdesc;
3836 if (jfunc->type == IPA_JF_CONST
3837 && (rdesc = jfunc_rdesc_usable (jfunc))
3838 && --rdesc->refcount == 0)
3840 symtab_node *symbol = symtab_node_for_jfunc (jfunc);
3841 if (!symbol)
3842 return false;
3844 return remove_described_reference (symbol, rdesc);
3846 return true;
3849 /* Try to find a destination for indirect edge IE that corresponds to a simple
3850 call or a call of a member function pointer and where the destination is a
3851 pointer formal parameter described by jump function JFUNC. TARGET_TYPE is
3852 the type of the parameter to which the result of JFUNC is passed. If it can
3853 be determined, return the newly direct edge, otherwise return NULL.
3854 NEW_ROOT and NEW_ROOT_INFO is the node and its info that JFUNC lattices are
3855 relative to. */
3857 static struct cgraph_edge *
3858 try_make_edge_direct_simple_call (struct cgraph_edge *ie,
3859 struct ipa_jump_func *jfunc, tree target_type,
3860 struct cgraph_node *new_root,
3861 class ipa_node_params *new_root_info)
3863 struct cgraph_edge *cs;
3864 tree target = NULL_TREE;
3865 bool agg_contents = ie->indirect_info->agg_contents;
3866 tree scalar = ipa_value_from_jfunc (new_root_info, jfunc, target_type);
3867 if (agg_contents)
3869 if (scalar)
3870 target = ipa_find_agg_cst_from_init (scalar, ie->indirect_info->offset,
3871 ie->indirect_info->by_ref);
3872 if (!target && ie->indirect_info->guaranteed_unmodified)
3873 target = ipa_find_agg_cst_from_jfunc_items (&jfunc->agg, new_root_info,
3874 new_root,
3875 ie->indirect_info->offset,
3876 ie->indirect_info->by_ref);
3878 else
3879 target = scalar;
3880 if (!target)
3881 return NULL;
3882 cs = ipa_make_edge_direct_to_target (ie, target);
3884 if (cs && !agg_contents)
3886 bool ok;
3887 gcc_checking_assert (cs->callee
3888 && (cs != ie
3889 || jfunc->type != IPA_JF_CONST
3890 || !symtab_node_for_jfunc (jfunc)
3891 || cs->callee == symtab_node_for_jfunc (jfunc)));
3892 ok = try_decrement_rdesc_refcount (jfunc);
3893 gcc_checking_assert (ok);
3896 return cs;
3899 /* Return the target to be used in cases of impossible devirtualization. IE
3900 and target (the latter can be NULL) are dumped when dumping is enabled. */
3902 tree
3903 ipa_impossible_devirt_target (struct cgraph_edge *ie, tree target)
3905 if (dump_file)
3907 if (target)
3908 fprintf (dump_file,
3909 "Type inconsistent devirtualization: %s->%s\n",
3910 ie->caller->dump_name (),
3911 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (target)));
3912 else
3913 fprintf (dump_file,
3914 "No devirtualization target in %s\n",
3915 ie->caller->dump_name ());
3917 tree new_target = builtin_decl_unreachable ();
3918 cgraph_node::get_create (new_target);
3919 return new_target;
3922 /* Try to find a destination for indirect edge IE that corresponds to a virtual
3923 call based on a formal parameter which is described by jump function JFUNC
3924 and if it can be determined, make it direct and return the direct edge.
3925 Otherwise, return NULL. CTX describes the polymorphic context that the
3926 parameter the call is based on brings along with it. NEW_ROOT and
3927 NEW_ROOT_INFO is the node and its info that JFUNC lattices are relative
3928 to. */
3930 static struct cgraph_edge *
3931 try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
3932 struct ipa_jump_func *jfunc,
3933 class ipa_polymorphic_call_context ctx,
3934 struct cgraph_node *new_root,
3935 class ipa_node_params *new_root_info)
3937 tree target = NULL;
3938 bool speculative = false;
3940 if (!opt_for_fn (ie->caller->decl, flag_devirtualize))
3941 return NULL;
3943 gcc_assert (!ie->indirect_info->by_ref);
3945 /* Try to do lookup via known virtual table pointer value. */
3946 if (!ie->indirect_info->vptr_changed
3947 || opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively))
3949 tree vtable;
3950 unsigned HOST_WIDE_INT offset;
3951 tree t = NULL_TREE;
3952 if (jfunc->type == IPA_JF_CONST)
3953 t = ipa_find_agg_cst_from_init (ipa_get_jf_constant (jfunc),
3954 ie->indirect_info->offset, true);
3955 if (!t)
3956 t = ipa_find_agg_cst_from_jfunc_items (&jfunc->agg, new_root_info,
3957 new_root,
3958 ie->indirect_info->offset, true);
3959 if (t && vtable_pointer_value_to_vtable (t, &vtable, &offset))
3961 bool can_refer;
3962 t = gimple_get_virt_method_for_vtable (ie->indirect_info->otr_token,
3963 vtable, offset, &can_refer);
3964 if (can_refer)
3966 if (!t
3967 || fndecl_built_in_p (t, BUILT_IN_UNREACHABLE,
3968 BUILT_IN_UNREACHABLE_TRAP)
3969 || !possible_polymorphic_call_target_p
3970 (ie, cgraph_node::get (t)))
3972 /* Do not speculate builtin_unreachable, it is stupid! */
3973 if (!ie->indirect_info->vptr_changed)
3974 target = ipa_impossible_devirt_target (ie, target);
3975 else
3976 target = NULL;
3978 else
3980 target = t;
3981 speculative = ie->indirect_info->vptr_changed;
3987 ipa_polymorphic_call_context ie_context (ie);
3988 vec <cgraph_node *>targets;
3989 bool final;
3991 ctx.offset_by (ie->indirect_info->offset);
3992 if (ie->indirect_info->vptr_changed)
3993 ctx.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
3994 ie->indirect_info->otr_type);
3995 ctx.combine_with (ie_context, ie->indirect_info->otr_type);
3996 targets = possible_polymorphic_call_targets
3997 (ie->indirect_info->otr_type,
3998 ie->indirect_info->otr_token,
3999 ctx, &final);
4000 if (final && targets.length () <= 1)
4002 speculative = false;
4003 if (targets.length () == 1)
4004 target = targets[0]->decl;
4005 else
4006 target = ipa_impossible_devirt_target (ie, NULL_TREE);
4008 else if (!target && opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively)
4009 && !ie->speculative && ie->maybe_hot_p ())
4011 cgraph_node *n;
4012 n = try_speculative_devirtualization (ie->indirect_info->otr_type,
4013 ie->indirect_info->otr_token,
4014 ie->indirect_info->context);
4015 if (n)
4017 target = n->decl;
4018 speculative = true;
4022 if (target)
4024 if (!possible_polymorphic_call_target_p
4025 (ie, cgraph_node::get_create (target)))
4027 if (speculative)
4028 return NULL;
4029 target = ipa_impossible_devirt_target (ie, target);
4031 return ipa_make_edge_direct_to_target (ie, target, speculative);
4033 else
4034 return NULL;
4037 /* Update the param called notes associated with NODE when CS is being inlined,
4038 assuming NODE is (potentially indirectly) inlined into CS->callee.
4039 Moreover, if the callee is discovered to be constant, create a new cgraph
4040 edge for it. Newly discovered indirect edges will be added to *NEW_EDGES,
4041 unless NEW_EDGES is NULL. Return true iff a new edge(s) were created. */
4043 static bool
4044 update_indirect_edges_after_inlining (struct cgraph_edge *cs,
4045 struct cgraph_node *node,
4046 vec<cgraph_edge *> *new_edges)
4048 class ipa_edge_args *top;
4049 struct cgraph_edge *ie, *next_ie, *new_direct_edge;
4050 struct cgraph_node *new_root;
4051 class ipa_node_params *new_root_info, *inlined_node_info;
4052 bool res = false;
4054 ipa_check_create_edge_args ();
4055 top = ipa_edge_args_sum->get (cs);
4056 new_root = cs->caller->inlined_to
4057 ? cs->caller->inlined_to : cs->caller;
4058 new_root_info = ipa_node_params_sum->get (new_root);
4059 inlined_node_info = ipa_node_params_sum->get (cs->callee->function_symbol ());
4061 for (ie = node->indirect_calls; ie; ie = next_ie)
4063 class cgraph_indirect_call_info *ici = ie->indirect_info;
4064 struct ipa_jump_func *jfunc;
4065 int param_index;
4067 next_ie = ie->next_callee;
4069 if (ici->param_index == -1)
4070 continue;
4072 /* We must check range due to calls with variable number of arguments: */
4073 if (!top || ici->param_index >= ipa_get_cs_argument_count (top))
4075 ici->param_index = -1;
4076 continue;
4079 param_index = ici->param_index;
4080 jfunc = ipa_get_ith_jump_func (top, param_index);
4082 auto_vec<cgraph_node *, 4> spec_targets;
4083 if (ie->speculative)
4084 for (cgraph_edge *direct = ie->first_speculative_call_target ();
4085 direct;
4086 direct = direct->next_speculative_call_target ())
4087 spec_targets.safe_push (direct->callee);
4089 if (!opt_for_fn (node->decl, flag_indirect_inlining))
4090 new_direct_edge = NULL;
4091 else if (ici->polymorphic)
4093 ipa_polymorphic_call_context ctx;
4094 ctx = ipa_context_from_jfunc (new_root_info, cs, param_index, jfunc);
4095 new_direct_edge = try_make_edge_direct_virtual_call (ie, jfunc, ctx,
4096 new_root,
4097 new_root_info);
4099 else
4101 tree target_type = ipa_get_type (inlined_node_info, param_index);
4102 new_direct_edge = try_make_edge_direct_simple_call (ie, jfunc,
4103 target_type,
4104 new_root,
4105 new_root_info);
4108 /* If speculation was removed, then we need to do nothing. */
4109 if (new_direct_edge && new_direct_edge != ie
4110 && spec_targets.contains (new_direct_edge->callee))
4112 new_direct_edge->indirect_inlining_edge = 1;
4113 res = true;
4114 if (!new_direct_edge->speculative)
4115 continue;
4117 else if (new_direct_edge)
4119 new_direct_edge->indirect_inlining_edge = 1;
4120 if (new_edges)
4122 new_edges->safe_push (new_direct_edge);
4123 res = true;
4125 /* If speculative edge was introduced we still need to update
4126 call info of the indirect edge. */
4127 if (!new_direct_edge->speculative)
4128 continue;
4130 if (jfunc->type == IPA_JF_PASS_THROUGH
4131 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
4133 if (ici->agg_contents
4134 && !ipa_get_jf_pass_through_agg_preserved (jfunc)
4135 && !ici->polymorphic)
4136 ici->param_index = -1;
4137 else
4139 ici->param_index = ipa_get_jf_pass_through_formal_id (jfunc);
4140 if (ici->polymorphic
4141 && !ipa_get_jf_pass_through_type_preserved (jfunc))
4142 ici->vptr_changed = true;
4143 ipa_set_param_used_by_indirect_call (new_root_info,
4144 ici->param_index, true);
4145 if (ici->polymorphic)
4146 ipa_set_param_used_by_polymorphic_call (new_root_info,
4147 ici->param_index, true);
4150 else if (jfunc->type == IPA_JF_ANCESTOR)
4152 if (ici->agg_contents
4153 && !ipa_get_jf_ancestor_agg_preserved (jfunc)
4154 && !ici->polymorphic)
4155 ici->param_index = -1;
4156 else
4158 ici->param_index = ipa_get_jf_ancestor_formal_id (jfunc);
4159 ici->offset += ipa_get_jf_ancestor_offset (jfunc);
4160 if (ici->polymorphic
4161 && !ipa_get_jf_ancestor_type_preserved (jfunc))
4162 ici->vptr_changed = true;
4163 ipa_set_param_used_by_indirect_call (new_root_info,
4164 ici->param_index, true);
4165 if (ici->polymorphic)
4166 ipa_set_param_used_by_polymorphic_call (new_root_info,
4167 ici->param_index, true);
4170 else
4171 /* Either we can find a destination for this edge now or never. */
4172 ici->param_index = -1;
4175 return res;
4178 /* Recursively traverse subtree of NODE (including node) made of inlined
4179 cgraph_edges when CS has been inlined and invoke
4180 update_indirect_edges_after_inlining on all nodes and
4181 update_jump_functions_after_inlining on all non-inlined edges that lead out
4182 of this subtree. Newly discovered indirect edges will be added to
4183 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were
4184 created. */
4186 static bool
4187 propagate_info_to_inlined_callees (struct cgraph_edge *cs,
4188 struct cgraph_node *node,
4189 vec<cgraph_edge *> *new_edges)
4191 struct cgraph_edge *e;
4192 bool res;
4194 res = update_indirect_edges_after_inlining (cs, node, new_edges);
4196 for (e = node->callees; e; e = e->next_callee)
4197 if (!e->inline_failed)
4198 res |= propagate_info_to_inlined_callees (cs, e->callee, new_edges);
4199 else
4200 update_jump_functions_after_inlining (cs, e);
4201 for (e = node->indirect_calls; e; e = e->next_callee)
4202 update_jump_functions_after_inlining (cs, e);
4204 return res;
4207 /* Combine two controlled uses counts as done during inlining. */
4209 static int
4210 combine_controlled_uses_counters (int c, int d)
4212 if (c == IPA_UNDESCRIBED_USE || d == IPA_UNDESCRIBED_USE)
4213 return IPA_UNDESCRIBED_USE;
4214 else
4215 return c + d - 1;
4218 /* Propagate number of controlled users from CS->caleee to the new root of the
4219 tree of inlined nodes. */
4221 static void
4222 propagate_controlled_uses (struct cgraph_edge *cs)
4224 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
4225 if (!args)
4226 return;
4227 struct cgraph_node *new_root = cs->caller->inlined_to
4228 ? cs->caller->inlined_to : cs->caller;
4229 ipa_node_params *new_root_info = ipa_node_params_sum->get (new_root);
4230 ipa_node_params *old_root_info = ipa_node_params_sum->get (cs->callee);
4231 int count, i;
4233 if (!old_root_info)
4234 return;
4236 count = MIN (ipa_get_cs_argument_count (args),
4237 ipa_get_param_count (old_root_info));
4238 for (i = 0; i < count; i++)
4240 struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
4241 struct ipa_cst_ref_desc *rdesc;
4243 if (jf->type == IPA_JF_PASS_THROUGH
4244 && !ipa_get_jf_pass_through_refdesc_decremented (jf))
4246 int src_idx, c, d;
4247 src_idx = ipa_get_jf_pass_through_formal_id (jf);
4248 c = ipa_get_controlled_uses (new_root_info, src_idx);
4249 d = ipa_get_controlled_uses (old_root_info, i);
4251 gcc_checking_assert (ipa_get_jf_pass_through_operation (jf)
4252 == NOP_EXPR || c == IPA_UNDESCRIBED_USE);
4253 c = combine_controlled_uses_counters (c, d);
4254 ipa_set_controlled_uses (new_root_info, src_idx, c);
4255 bool lderef = true;
4256 if (c != IPA_UNDESCRIBED_USE)
4258 lderef = (ipa_get_param_load_dereferenced (new_root_info, src_idx)
4259 || ipa_get_param_load_dereferenced (old_root_info, i));
4260 ipa_set_param_load_dereferenced (new_root_info, src_idx, lderef);
4263 if (c == 0 && !lderef && new_root_info->ipcp_orig_node)
4265 struct cgraph_node *n;
4266 struct ipa_ref *ref;
4267 tree t = new_root_info->known_csts[src_idx];
4269 if (t && TREE_CODE (t) == ADDR_EXPR
4270 && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
4271 && (n = cgraph_node::get (TREE_OPERAND (t, 0)))
4272 && (ref = new_root->find_reference (n, NULL, 0,
4273 IPA_REF_ADDR)))
4275 if (dump_file)
4276 fprintf (dump_file, "ipa-prop: Removing cloning-created "
4277 "reference from %s to %s.\n",
4278 new_root->dump_name (),
4279 n->dump_name ());
4280 ref->remove_reference ();
4284 else if (jf->type == IPA_JF_CONST
4285 && (rdesc = jfunc_rdesc_usable (jf)))
4287 int d = ipa_get_controlled_uses (old_root_info, i);
4288 int c = rdesc->refcount;
4289 tree cst = ipa_get_jf_constant (jf);
4290 rdesc->refcount = combine_controlled_uses_counters (c, d);
4291 if (rdesc->refcount != IPA_UNDESCRIBED_USE
4292 && ipa_get_param_load_dereferenced (old_root_info, i)
4293 && TREE_CODE (cst) == ADDR_EXPR
4294 && VAR_P (TREE_OPERAND (cst, 0)))
4296 symtab_node *n = symtab_node::get (TREE_OPERAND (cst, 0));
4297 new_root->create_reference (n, IPA_REF_LOAD, NULL);
4298 if (dump_file)
4299 fprintf (dump_file, "ipa-prop: Address IPA constant will reach "
4300 "a load so adding LOAD reference from %s to %s.\n",
4301 new_root->dump_name (), n->dump_name ());
4303 if (rdesc->refcount == 0)
4305 gcc_checking_assert (TREE_CODE (cst) == ADDR_EXPR
4306 && ((TREE_CODE (TREE_OPERAND (cst, 0))
4307 == FUNCTION_DECL)
4308 || VAR_P (TREE_OPERAND (cst, 0))));
4310 symtab_node *n = symtab_node::get (TREE_OPERAND (cst, 0));
4311 if (n)
4313 remove_described_reference (n, rdesc);
4314 cgraph_node *clone = cs->caller;
4315 while (clone->inlined_to
4316 && clone->ipcp_clone
4317 && clone != rdesc->cs->caller)
4319 struct ipa_ref *ref;
4320 ref = clone->find_reference (n, NULL, 0, IPA_REF_ADDR);
4321 if (ref)
4323 if (dump_file)
4324 fprintf (dump_file, "ipa-prop: Removing "
4325 "cloning-created reference "
4326 "from %s to %s.\n",
4327 clone->dump_name (),
4328 n->dump_name ());
4329 ref->remove_reference ();
4331 clone = clone->callers->caller;
4338 for (i = ipa_get_param_count (old_root_info);
4339 i < ipa_get_cs_argument_count (args);
4340 i++)
4342 struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
4344 if (jf->type == IPA_JF_CONST)
4346 struct ipa_cst_ref_desc *rdesc = jfunc_rdesc_usable (jf);
4347 if (rdesc)
4348 rdesc->refcount = IPA_UNDESCRIBED_USE;
4350 else if (jf->type == IPA_JF_PASS_THROUGH)
4351 ipa_set_controlled_uses (new_root_info,
4352 jf->value.pass_through.formal_id,
4353 IPA_UNDESCRIBED_USE);
4357 /* Update jump functions and call note functions on inlining the call site CS.
4358 CS is expected to lead to a node already cloned by
4359 cgraph_clone_inline_nodes. Newly discovered indirect edges will be added to
4360 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were +
4361 created. */
4363 bool
4364 ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
4365 vec<cgraph_edge *> *new_edges)
4367 bool changed;
4368 /* Do nothing if the preparation phase has not been carried out yet
4369 (i.e. during early inlining). */
4370 if (!ipa_node_params_sum)
4371 return false;
4372 gcc_assert (ipa_edge_args_sum);
4374 propagate_controlled_uses (cs);
4375 changed = propagate_info_to_inlined_callees (cs, cs->callee, new_edges);
4376 ipa_node_params_sum->remove (cs->callee);
4378 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
4379 if (args)
4381 bool ok = true;
4382 if (args->jump_functions)
4384 struct ipa_jump_func *jf;
4385 int i;
4386 FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
4387 if (jf->type == IPA_JF_CONST
4388 && ipa_get_jf_constant_rdesc (jf))
4390 ok = false;
4391 break;
4394 if (ok)
4395 ipa_edge_args_sum->remove (cs);
4397 if (ipcp_transformation_sum)
4398 ipcp_transformation_sum->remove (cs->callee);
4400 return changed;
4403 /* Ensure that array of edge arguments infos is big enough to accommodate a
4404 structure for all edges and reallocates it if not. Also, allocate
4405 associated hash tables is they do not already exist. */
4407 void
4408 ipa_check_create_edge_args (void)
4410 if (!ipa_edge_args_sum)
4411 ipa_edge_args_sum
4412 = (new (ggc_alloc_no_dtor<ipa_edge_args_sum_t> ())
4413 ipa_edge_args_sum_t (symtab, true));
4414 if (!ipa_vr_hash_table)
4415 ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
4418 /* Free all ipa_edge structures. */
4420 void
4421 ipa_free_all_edge_args (void)
4423 if (!ipa_edge_args_sum)
4424 return;
4426 ggc_delete (ipa_edge_args_sum);
4427 ipa_edge_args_sum = NULL;
4430 /* Free all ipa_node_params structures. */
4432 void
4433 ipa_free_all_node_params (void)
4435 if (ipa_node_params_sum)
4436 ggc_delete (ipa_node_params_sum);
4437 ipa_node_params_sum = NULL;
4440 /* Initialize IPA CP transformation summary and also allocate any necessary hash
4441 tables if they do not already exist. */
4443 void
4444 ipcp_transformation_initialize (void)
4446 if (!ipa_vr_hash_table)
4447 ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
4448 if (ipcp_transformation_sum == NULL)
4450 ipcp_transformation_sum = ipcp_transformation_t::create_ggc (symtab);
4451 ipcp_transformation_sum->disable_insertion_hook ();
4455 /* Release the IPA CP transformation summary. */
4457 void
4458 ipcp_free_transformation_sum (void)
4460 if (!ipcp_transformation_sum)
4461 return;
4463 ipcp_transformation_sum->~function_summary<ipcp_transformation *> ();
4464 ggc_free (ipcp_transformation_sum);
4465 ipcp_transformation_sum = NULL;
4468 /* Set the aggregate replacements of NODE to be AGGVALS. */
4470 void
4471 ipa_set_node_agg_value_chain (struct cgraph_node *node,
4472 vec<ipa_argagg_value, va_gc> *aggs)
4474 ipcp_transformation_initialize ();
4475 ipcp_transformation *s = ipcp_transformation_sum->get_create (node);
4476 s->m_agg_values = aggs;
4479 /* Hook that is called by cgraph.cc when an edge is removed. Adjust reference
4480 count data structures accordingly. */
4482 void
4483 ipa_edge_args_sum_t::remove (cgraph_edge *cs, ipa_edge_args *args)
4485 if (args->jump_functions)
4487 struct ipa_jump_func *jf;
4488 int i;
4489 FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
4491 struct ipa_cst_ref_desc *rdesc;
4492 try_decrement_rdesc_refcount (jf);
4493 if (jf->type == IPA_JF_CONST
4494 && (rdesc = ipa_get_jf_constant_rdesc (jf))
4495 && rdesc->cs == cs)
4496 rdesc->cs = NULL;
4501 /* Method invoked when an edge is duplicated. Copy ipa_edge_args and adjust
4502 reference count data strucutres accordingly. */
4504 void
4505 ipa_edge_args_sum_t::duplicate (cgraph_edge *src, cgraph_edge *dst,
4506 ipa_edge_args *old_args, ipa_edge_args *new_args)
4508 unsigned int i;
4510 new_args->jump_functions = vec_safe_copy (old_args->jump_functions);
4511 if (old_args->polymorphic_call_contexts)
4512 new_args->polymorphic_call_contexts
4513 = vec_safe_copy (old_args->polymorphic_call_contexts);
4515 for (i = 0; i < vec_safe_length (old_args->jump_functions); i++)
4517 struct ipa_jump_func *src_jf = ipa_get_ith_jump_func (old_args, i);
4518 struct ipa_jump_func *dst_jf = ipa_get_ith_jump_func (new_args, i);
4520 dst_jf->agg.items = vec_safe_copy (dst_jf->agg.items);
4522 if (src_jf->type == IPA_JF_CONST)
4524 struct ipa_cst_ref_desc *src_rdesc = jfunc_rdesc_usable (src_jf);
4526 if (!src_rdesc)
4527 dst_jf->value.constant.rdesc = NULL;
4528 else if (src->caller == dst->caller)
4530 /* Creation of a speculative edge. If the source edge is the one
4531 grabbing a reference, we must create a new (duplicate)
4532 reference description. Otherwise they refer to the same
4533 description corresponding to a reference taken in a function
4534 src->caller is inlined to. In that case we just must
4535 increment the refcount. */
4536 if (src_rdesc->cs == src)
4538 symtab_node *n = symtab_node_for_jfunc (src_jf);
4539 gcc_checking_assert (n);
4540 ipa_ref *ref
4541 = src->caller->find_reference (n, src->call_stmt,
4542 src->lto_stmt_uid,
4543 IPA_REF_ADDR);
4544 gcc_checking_assert (ref);
4545 dst->caller->clone_reference (ref, ref->stmt);
4547 ipa_cst_ref_desc *dst_rdesc = ipa_refdesc_pool.allocate ();
4548 dst_rdesc->cs = dst;
4549 dst_rdesc->refcount = src_rdesc->refcount;
4550 dst_rdesc->next_duplicate = NULL;
4551 dst_jf->value.constant.rdesc = dst_rdesc;
4553 else
4555 src_rdesc->refcount++;
4556 dst_jf->value.constant.rdesc = src_rdesc;
4559 else if (src_rdesc->cs == src)
4561 struct ipa_cst_ref_desc *dst_rdesc = ipa_refdesc_pool.allocate ();
4562 dst_rdesc->cs = dst;
4563 dst_rdesc->refcount = src_rdesc->refcount;
4564 dst_rdesc->next_duplicate = src_rdesc->next_duplicate;
4565 src_rdesc->next_duplicate = dst_rdesc;
4566 dst_jf->value.constant.rdesc = dst_rdesc;
4568 else
4570 struct ipa_cst_ref_desc *dst_rdesc;
4571 /* This can happen during inlining, when a JFUNC can refer to a
4572 reference taken in a function up in the tree of inline clones.
4573 We need to find the duplicate that refers to our tree of
4574 inline clones. */
4576 gcc_assert (dst->caller->inlined_to);
4577 for (dst_rdesc = src_rdesc->next_duplicate;
4578 dst_rdesc;
4579 dst_rdesc = dst_rdesc->next_duplicate)
4581 struct cgraph_node *top;
4582 top = dst_rdesc->cs->caller->inlined_to
4583 ? dst_rdesc->cs->caller->inlined_to
4584 : dst_rdesc->cs->caller;
4585 if (dst->caller->inlined_to == top)
4586 break;
4588 gcc_assert (dst_rdesc);
4589 dst_jf->value.constant.rdesc = dst_rdesc;
4592 else if (dst_jf->type == IPA_JF_PASS_THROUGH
4593 && src->caller == dst->caller)
4595 struct cgraph_node *inline_root = dst->caller->inlined_to
4596 ? dst->caller->inlined_to : dst->caller;
4597 ipa_node_params *root_info = ipa_node_params_sum->get (inline_root);
4598 int idx = ipa_get_jf_pass_through_formal_id (dst_jf);
4600 int c = ipa_get_controlled_uses (root_info, idx);
4601 if (c != IPA_UNDESCRIBED_USE)
4603 c++;
4604 ipa_set_controlled_uses (root_info, idx, c);
4610 /* Analyze newly added function into callgraph. */
4612 static void
4613 ipa_add_new_function (cgraph_node *node, void *data ATTRIBUTE_UNUSED)
4615 if (node->has_gimple_body_p ())
4616 ipa_analyze_node (node);
4619 /* Hook that is called by summary when a node is duplicated. */
4621 void
4622 ipa_node_params_t::duplicate(cgraph_node *, cgraph_node *,
4623 ipa_node_params *old_info,
4624 ipa_node_params *new_info)
4626 new_info->descriptors = vec_safe_copy (old_info->descriptors);
4627 gcc_assert (new_info->lattices.is_empty ());
4628 new_info->ipcp_orig_node = old_info->ipcp_orig_node;
4629 new_info->known_csts = old_info->known_csts.copy ();
4630 new_info->known_contexts = old_info->known_contexts.copy ();
4632 new_info->analysis_done = old_info->analysis_done;
4633 new_info->node_enqueued = old_info->node_enqueued;
4634 new_info->versionable = old_info->versionable;
4637 /* Duplication of ipcp transformation summaries. */
4639 void
4640 ipcp_transformation_t::duplicate(cgraph_node *, cgraph_node *dst,
4641 ipcp_transformation *src_trans,
4642 ipcp_transformation *dst_trans)
4644 /* Avoid redundant work of duplicating vectors we will never use. */
4645 if (dst->inlined_to)
4646 return;
4647 dst_trans->m_agg_values = vec_safe_copy (src_trans->m_agg_values);
4648 dst_trans->m_vr = vec_safe_copy (src_trans->m_vr);
4651 /* Register our cgraph hooks if they are not already there. */
4653 void
4654 ipa_register_cgraph_hooks (void)
4656 ipa_check_create_node_params ();
4657 ipa_check_create_edge_args ();
4659 function_insertion_hook_holder =
4660 symtab->add_cgraph_insertion_hook (&ipa_add_new_function, NULL);
4663 /* Unregister our cgraph hooks if they are not already there. */
4665 static void
4666 ipa_unregister_cgraph_hooks (void)
4668 if (function_insertion_hook_holder)
4669 symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
4670 function_insertion_hook_holder = NULL;
4673 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
4674 longer needed after ipa-cp. */
4676 void
4677 ipa_free_all_structures_after_ipa_cp (void)
4679 if (!optimize && !in_lto_p)
4681 ipa_free_all_edge_args ();
4682 ipa_free_all_node_params ();
4683 ipcp_sources_pool.release ();
4684 ipcp_cst_values_pool.release ();
4685 ipcp_poly_ctx_values_pool.release ();
4686 ipcp_agg_lattice_pool.release ();
4687 ipa_unregister_cgraph_hooks ();
4688 ipa_refdesc_pool.release ();
4692 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
4693 longer needed after indirect inlining. */
4695 void
4696 ipa_free_all_structures_after_iinln (void)
4698 ipa_free_all_edge_args ();
4699 ipa_free_all_node_params ();
4700 ipa_unregister_cgraph_hooks ();
4701 ipcp_sources_pool.release ();
4702 ipcp_cst_values_pool.release ();
4703 ipcp_poly_ctx_values_pool.release ();
4704 ipcp_agg_lattice_pool.release ();
4705 ipa_refdesc_pool.release ();
4708 /* Print ipa_tree_map data structures of all functions in the
4709 callgraph to F. */
4711 void
4712 ipa_print_node_params (FILE *f, struct cgraph_node *node)
4714 int i, count;
4715 class ipa_node_params *info;
4717 if (!node->definition)
4718 return;
4719 info = ipa_node_params_sum->get (node);
4720 fprintf (f, " function %s parameter descriptors:\n", node->dump_name ());
4721 if (!info)
4723 fprintf (f, " no params return\n");
4724 return;
4726 count = ipa_get_param_count (info);
4727 for (i = 0; i < count; i++)
4729 int c;
4731 fprintf (f, " ");
4732 ipa_dump_param (f, info, i);
4733 if (ipa_is_param_used (info, i))
4734 fprintf (f, " used");
4735 if (ipa_is_param_used_by_ipa_predicates (info, i))
4736 fprintf (f, " used_by_ipa_predicates");
4737 if (ipa_is_param_used_by_indirect_call (info, i))
4738 fprintf (f, " used_by_indirect_call");
4739 if (ipa_is_param_used_by_polymorphic_call (info, i))
4740 fprintf (f, " used_by_polymorphic_call");
4741 c = ipa_get_controlled_uses (info, i);
4742 if (c == IPA_UNDESCRIBED_USE)
4743 fprintf (f, " undescribed_use");
4744 else
4745 fprintf (f, " controlled_uses=%i %s", c,
4746 ipa_get_param_load_dereferenced (info, i)
4747 ? "(load_dereferenced)" : "");
4748 fprintf (f, "\n");
4752 /* Print ipa_tree_map data structures of all functions in the
4753 callgraph to F. */
4755 void
4756 ipa_print_all_params (FILE * f)
4758 struct cgraph_node *node;
4760 fprintf (f, "\nFunction parameters:\n");
4761 FOR_EACH_FUNCTION (node)
4762 ipa_print_node_params (f, node);
4765 /* Stream out jump function JUMP_FUNC to OB. */
4767 static void
4768 ipa_write_jump_function (struct output_block *ob,
4769 struct ipa_jump_func *jump_func)
4771 struct ipa_agg_jf_item *item;
4772 struct bitpack_d bp;
4773 int i, count;
4774 int flag = 0;
4776 /* ADDR_EXPRs are very comon IP invariants; save some streamer data
4777 as well as WPA memory by handling them specially. */
4778 if (jump_func->type == IPA_JF_CONST
4779 && TREE_CODE (jump_func->value.constant.value) == ADDR_EXPR)
4780 flag = 1;
4782 streamer_write_uhwi (ob, jump_func->type * 2 + flag);
4783 switch (jump_func->type)
4785 case IPA_JF_UNKNOWN:
4786 break;
4787 case IPA_JF_CONST:
4788 gcc_assert (
4789 EXPR_LOCATION (jump_func->value.constant.value) == UNKNOWN_LOCATION);
4790 stream_write_tree (ob,
4791 flag
4792 ? TREE_OPERAND (jump_func->value.constant.value, 0)
4793 : jump_func->value.constant.value, true);
4794 break;
4795 case IPA_JF_PASS_THROUGH:
4796 streamer_write_uhwi (ob, jump_func->value.pass_through.operation);
4797 if (jump_func->value.pass_through.operation == NOP_EXPR)
4799 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4800 bp = bitpack_create (ob->main_stream);
4801 bp_pack_value (&bp, jump_func->value.pass_through.agg_preserved, 1);
4802 gcc_assert (!jump_func->value.pass_through.refdesc_decremented);
4803 streamer_write_bitpack (&bp);
4805 else if (TREE_CODE_CLASS (jump_func->value.pass_through.operation)
4806 == tcc_unary)
4807 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4808 else
4810 stream_write_tree (ob, jump_func->value.pass_through.operand, true);
4811 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4813 break;
4814 case IPA_JF_ANCESTOR:
4815 streamer_write_uhwi (ob, jump_func->value.ancestor.offset);
4816 streamer_write_uhwi (ob, jump_func->value.ancestor.formal_id);
4817 bp = bitpack_create (ob->main_stream);
4818 bp_pack_value (&bp, jump_func->value.ancestor.agg_preserved, 1);
4819 bp_pack_value (&bp, jump_func->value.ancestor.keep_null, 1);
4820 streamer_write_bitpack (&bp);
4821 break;
4822 default:
4823 fatal_error (UNKNOWN_LOCATION, "invalid jump function in LTO stream");
4826 count = vec_safe_length (jump_func->agg.items);
4827 streamer_write_uhwi (ob, count);
4828 if (count)
4830 bp = bitpack_create (ob->main_stream);
4831 bp_pack_value (&bp, jump_func->agg.by_ref, 1);
4832 streamer_write_bitpack (&bp);
4835 FOR_EACH_VEC_SAFE_ELT (jump_func->agg.items, i, item)
4837 stream_write_tree (ob, item->type, true);
4838 streamer_write_uhwi (ob, item->offset);
4839 streamer_write_uhwi (ob, item->jftype);
4840 switch (item->jftype)
4842 case IPA_JF_UNKNOWN:
4843 break;
4844 case IPA_JF_CONST:
4845 stream_write_tree (ob, item->value.constant, true);
4846 break;
4847 case IPA_JF_PASS_THROUGH:
4848 case IPA_JF_LOAD_AGG:
4849 streamer_write_uhwi (ob, item->value.pass_through.operation);
4850 streamer_write_uhwi (ob, item->value.pass_through.formal_id);
4851 if (TREE_CODE_CLASS (item->value.pass_through.operation)
4852 != tcc_unary)
4853 stream_write_tree (ob, item->value.pass_through.operand, true);
4854 if (item->jftype == IPA_JF_LOAD_AGG)
4856 stream_write_tree (ob, item->value.load_agg.type, true);
4857 streamer_write_uhwi (ob, item->value.load_agg.offset);
4858 bp = bitpack_create (ob->main_stream);
4859 bp_pack_value (&bp, item->value.load_agg.by_ref, 1);
4860 streamer_write_bitpack (&bp);
4862 break;
4863 default:
4864 fatal_error (UNKNOWN_LOCATION,
4865 "invalid jump function in LTO stream");
4869 bp = bitpack_create (ob->main_stream);
4870 if (jump_func->m_vr)
4871 jump_func->m_vr->streamer_write (ob);
4872 else
4874 bp_pack_value (&bp, false, 1);
4875 streamer_write_bitpack (&bp);
4879 /* Read in jump function JUMP_FUNC from IB. */
4881 static void
4882 ipa_read_jump_function (class lto_input_block *ib,
4883 struct ipa_jump_func *jump_func,
4884 struct cgraph_edge *cs,
4885 class data_in *data_in,
4886 bool prevails)
4888 enum jump_func_type jftype;
4889 enum tree_code operation;
4890 int i, count;
4891 int val = streamer_read_uhwi (ib);
4892 bool flag = val & 1;
4894 jftype = (enum jump_func_type) (val / 2);
4895 switch (jftype)
4897 case IPA_JF_UNKNOWN:
4898 ipa_set_jf_unknown (jump_func);
4899 break;
4900 case IPA_JF_CONST:
4902 tree t = stream_read_tree (ib, data_in);
4903 if (flag && prevails)
4904 t = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
4905 ipa_set_jf_constant (jump_func, t, cs);
4907 break;
4908 case IPA_JF_PASS_THROUGH:
4909 operation = (enum tree_code) streamer_read_uhwi (ib);
4910 if (operation == NOP_EXPR)
4912 int formal_id = streamer_read_uhwi (ib);
4913 struct bitpack_d bp = streamer_read_bitpack (ib);
4914 bool agg_preserved = bp_unpack_value (&bp, 1);
4915 ipa_set_jf_simple_pass_through (jump_func, formal_id, agg_preserved);
4917 else if (TREE_CODE_CLASS (operation) == tcc_unary)
4919 int formal_id = streamer_read_uhwi (ib);
4920 ipa_set_jf_unary_pass_through (jump_func, formal_id, operation);
4922 else
4924 tree operand = stream_read_tree (ib, data_in);
4925 int formal_id = streamer_read_uhwi (ib);
4926 ipa_set_jf_arith_pass_through (jump_func, formal_id, operand,
4927 operation);
4929 break;
4930 case IPA_JF_ANCESTOR:
4932 HOST_WIDE_INT offset = streamer_read_uhwi (ib);
4933 int formal_id = streamer_read_uhwi (ib);
4934 struct bitpack_d bp = streamer_read_bitpack (ib);
4935 bool agg_preserved = bp_unpack_value (&bp, 1);
4936 bool keep_null = bp_unpack_value (&bp, 1);
4937 ipa_set_ancestor_jf (jump_func, offset, formal_id, agg_preserved,
4938 keep_null);
4939 break;
4941 default:
4942 fatal_error (UNKNOWN_LOCATION, "invalid jump function in LTO stream");
4945 count = streamer_read_uhwi (ib);
4946 if (prevails)
4948 jump_func->agg.items = NULL;
4949 vec_safe_reserve (jump_func->agg.items, count, true);
4951 if (count)
4953 struct bitpack_d bp = streamer_read_bitpack (ib);
4954 jump_func->agg.by_ref = bp_unpack_value (&bp, 1);
4956 for (i = 0; i < count; i++)
4958 struct ipa_agg_jf_item item;
4959 item.type = stream_read_tree (ib, data_in);
4960 item.offset = streamer_read_uhwi (ib);
4961 item.jftype = (enum jump_func_type) streamer_read_uhwi (ib);
4963 switch (item.jftype)
4965 case IPA_JF_UNKNOWN:
4966 break;
4967 case IPA_JF_CONST:
4968 item.value.constant = stream_read_tree (ib, data_in);
4969 break;
4970 case IPA_JF_PASS_THROUGH:
4971 case IPA_JF_LOAD_AGG:
4972 operation = (enum tree_code) streamer_read_uhwi (ib);
4973 item.value.pass_through.operation = operation;
4974 item.value.pass_through.formal_id = streamer_read_uhwi (ib);
4975 if (TREE_CODE_CLASS (operation) == tcc_unary)
4976 item.value.pass_through.operand = NULL_TREE;
4977 else
4978 item.value.pass_through.operand = stream_read_tree (ib, data_in);
4979 if (item.jftype == IPA_JF_LOAD_AGG)
4981 struct bitpack_d bp;
4982 item.value.load_agg.type = stream_read_tree (ib, data_in);
4983 item.value.load_agg.offset = streamer_read_uhwi (ib);
4984 bp = streamer_read_bitpack (ib);
4985 item.value.load_agg.by_ref = bp_unpack_value (&bp, 1);
4987 break;
4988 default:
4989 fatal_error (UNKNOWN_LOCATION,
4990 "invalid jump function in LTO stream");
4992 if (prevails)
4993 jump_func->agg.items->quick_push (item);
4996 ipa_vr vr;
4997 vr.streamer_read (ib, data_in);
4998 if (vr.known_p ())
5000 if (prevails)
5001 ipa_set_jfunc_vr (jump_func, vr);
5003 else
5004 jump_func->m_vr = NULL;
5007 /* Stream out parts of cgraph_indirect_call_info corresponding to CS that are
5008 relevant to indirect inlining to OB. */
5010 static void
5011 ipa_write_indirect_edge_info (struct output_block *ob,
5012 struct cgraph_edge *cs)
5014 class cgraph_indirect_call_info *ii = cs->indirect_info;
5015 struct bitpack_d bp;
5017 streamer_write_hwi (ob, ii->param_index);
5018 bp = bitpack_create (ob->main_stream);
5019 bp_pack_value (&bp, ii->polymorphic, 1);
5020 bp_pack_value (&bp, ii->agg_contents, 1);
5021 bp_pack_value (&bp, ii->member_ptr, 1);
5022 bp_pack_value (&bp, ii->by_ref, 1);
5023 bp_pack_value (&bp, ii->guaranteed_unmodified, 1);
5024 bp_pack_value (&bp, ii->vptr_changed, 1);
5025 streamer_write_bitpack (&bp);
5026 if (ii->agg_contents || ii->polymorphic)
5027 streamer_write_hwi (ob, ii->offset);
5028 else
5029 gcc_assert (ii->offset == 0);
5031 if (ii->polymorphic)
5033 streamer_write_hwi (ob, ii->otr_token);
5034 stream_write_tree (ob, ii->otr_type, true);
5035 ii->context.stream_out (ob);
5039 /* Read in parts of cgraph_indirect_call_info corresponding to CS that are
5040 relevant to indirect inlining from IB. */
5042 static void
5043 ipa_read_indirect_edge_info (class lto_input_block *ib,
5044 class data_in *data_in,
5045 struct cgraph_edge *cs,
5046 class ipa_node_params *info)
5048 class cgraph_indirect_call_info *ii = cs->indirect_info;
5049 struct bitpack_d bp;
5051 ii->param_index = (int) streamer_read_hwi (ib);
5052 bp = streamer_read_bitpack (ib);
5053 ii->polymorphic = bp_unpack_value (&bp, 1);
5054 ii->agg_contents = bp_unpack_value (&bp, 1);
5055 ii->member_ptr = bp_unpack_value (&bp, 1);
5056 ii->by_ref = bp_unpack_value (&bp, 1);
5057 ii->guaranteed_unmodified = bp_unpack_value (&bp, 1);
5058 ii->vptr_changed = bp_unpack_value (&bp, 1);
5059 if (ii->agg_contents || ii->polymorphic)
5060 ii->offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
5061 else
5062 ii->offset = 0;
5063 if (ii->polymorphic)
5065 ii->otr_token = (HOST_WIDE_INT) streamer_read_hwi (ib);
5066 ii->otr_type = stream_read_tree (ib, data_in);
5067 ii->context.stream_in (ib, data_in);
5069 if (info && ii->param_index >= 0)
5071 if (ii->polymorphic)
5072 ipa_set_param_used_by_polymorphic_call (info,
5073 ii->param_index , true);
5074 ipa_set_param_used_by_indirect_call (info,
5075 ii->param_index, true);
5079 /* Stream out NODE info to OB. */
5081 static void
5082 ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
5084 int node_ref;
5085 lto_symtab_encoder_t encoder;
5086 ipa_node_params *info = ipa_node_params_sum->get (node);
5087 int j;
5088 struct cgraph_edge *e;
5089 struct bitpack_d bp;
5091 encoder = ob->decl_state->symtab_node_encoder;
5092 node_ref = lto_symtab_encoder_encode (encoder, node);
5093 streamer_write_uhwi (ob, node_ref);
5095 streamer_write_uhwi (ob, ipa_get_param_count (info));
5096 for (j = 0; j < ipa_get_param_count (info); j++)
5097 streamer_write_uhwi (ob, ipa_get_param_move_cost (info, j));
5098 bp = bitpack_create (ob->main_stream);
5099 gcc_assert (info->analysis_done
5100 || ipa_get_param_count (info) == 0);
5101 gcc_assert (!info->node_enqueued);
5102 gcc_assert (!info->ipcp_orig_node);
5103 for (j = 0; j < ipa_get_param_count (info); j++)
5105 /* TODO: We could just not stream the bit in the undescribed case. */
5106 bool d = (ipa_get_controlled_uses (info, j) != IPA_UNDESCRIBED_USE)
5107 ? ipa_get_param_load_dereferenced (info, j) : true;
5108 bp_pack_value (&bp, d, 1);
5109 bp_pack_value (&bp, ipa_is_param_used (info, j), 1);
5111 streamer_write_bitpack (&bp);
5112 for (j = 0; j < ipa_get_param_count (info); j++)
5114 streamer_write_hwi (ob, ipa_get_controlled_uses (info, j));
5115 stream_write_tree (ob, ipa_get_type (info, j), true);
5117 for (e = node->callees; e; e = e->next_callee)
5119 ipa_edge_args *args = ipa_edge_args_sum->get (e);
5121 if (!args)
5123 streamer_write_uhwi (ob, 0);
5124 continue;
5127 streamer_write_uhwi (ob,
5128 ipa_get_cs_argument_count (args) * 2
5129 + (args->polymorphic_call_contexts != NULL));
5130 for (j = 0; j < ipa_get_cs_argument_count (args); j++)
5132 ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
5133 if (args->polymorphic_call_contexts != NULL)
5134 ipa_get_ith_polymorhic_call_context (args, j)->stream_out (ob);
5137 for (e = node->indirect_calls; e; e = e->next_callee)
5139 ipa_edge_args *args = ipa_edge_args_sum->get (e);
5140 if (!args)
5141 streamer_write_uhwi (ob, 0);
5142 else
5144 streamer_write_uhwi (ob,
5145 ipa_get_cs_argument_count (args) * 2
5146 + (args->polymorphic_call_contexts != NULL));
5147 for (j = 0; j < ipa_get_cs_argument_count (args); j++)
5149 ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
5150 if (args->polymorphic_call_contexts != NULL)
5151 ipa_get_ith_polymorhic_call_context (args, j)->stream_out (ob);
5154 ipa_write_indirect_edge_info (ob, e);
5158 /* Stream in edge E from IB. */
5160 static void
5161 ipa_read_edge_info (class lto_input_block *ib,
5162 class data_in *data_in,
5163 struct cgraph_edge *e, bool prevails)
5165 int count = streamer_read_uhwi (ib);
5166 bool contexts_computed = count & 1;
5168 count /= 2;
5169 if (!count)
5170 return;
5171 if (prevails
5172 && (e->possibly_call_in_translation_unit_p ()
5173 /* Also stream in jump functions to builtins in hope that they
5174 will get fnspecs. */
5175 || fndecl_built_in_p (e->callee->decl, BUILT_IN_NORMAL)))
5177 ipa_edge_args *args = ipa_edge_args_sum->get_create (e);
5178 vec_safe_grow_cleared (args->jump_functions, count, true);
5179 if (contexts_computed)
5180 vec_safe_grow_cleared (args->polymorphic_call_contexts, count, true);
5181 for (int k = 0; k < count; k++)
5183 ipa_read_jump_function (ib, ipa_get_ith_jump_func (args, k), e,
5184 data_in, prevails);
5185 if (contexts_computed)
5186 ipa_get_ith_polymorhic_call_context (args, k)->stream_in
5187 (ib, data_in);
5190 else
5192 for (int k = 0; k < count; k++)
5194 struct ipa_jump_func dummy;
5195 ipa_read_jump_function (ib, &dummy, e,
5196 data_in, prevails);
5197 if (contexts_computed)
5199 class ipa_polymorphic_call_context ctx;
5200 ctx.stream_in (ib, data_in);
5206 /* Stream in NODE info from IB. */
5208 static void
5209 ipa_read_node_info (class lto_input_block *ib, struct cgraph_node *node,
5210 class data_in *data_in)
5212 int k;
5213 struct cgraph_edge *e;
5214 struct bitpack_d bp;
5215 bool prevails = node->prevailing_p ();
5216 ipa_node_params *info
5217 = prevails ? ipa_node_params_sum->get_create (node) : NULL;
5219 int param_count = streamer_read_uhwi (ib);
5220 if (prevails)
5222 ipa_alloc_node_params (node, param_count);
5223 for (k = 0; k < param_count; k++)
5224 (*info->descriptors)[k].move_cost = streamer_read_uhwi (ib);
5225 if (ipa_get_param_count (info) != 0)
5226 info->analysis_done = true;
5227 info->node_enqueued = false;
5229 else
5230 for (k = 0; k < param_count; k++)
5231 streamer_read_uhwi (ib);
5233 bp = streamer_read_bitpack (ib);
5234 for (k = 0; k < param_count; k++)
5236 bool load_dereferenced = bp_unpack_value (&bp, 1);
5237 bool used = bp_unpack_value (&bp, 1);
5239 if (prevails)
5241 ipa_set_param_load_dereferenced (info, k, load_dereferenced);
5242 ipa_set_param_used (info, k, used);
5245 for (k = 0; k < param_count; k++)
5247 int nuses = streamer_read_hwi (ib);
5248 tree type = stream_read_tree (ib, data_in);
5250 if (prevails)
5252 ipa_set_controlled_uses (info, k, nuses);
5253 (*info->descriptors)[k].decl_or_type = type;
5256 for (e = node->callees; e; e = e->next_callee)
5257 ipa_read_edge_info (ib, data_in, e, prevails);
5258 for (e = node->indirect_calls; e; e = e->next_callee)
5260 ipa_read_edge_info (ib, data_in, e, prevails);
5261 ipa_read_indirect_edge_info (ib, data_in, e, info);
5265 /* Write jump functions for nodes in SET. */
5267 void
5268 ipa_prop_write_jump_functions (void)
5270 struct output_block *ob;
5271 unsigned int count = 0;
5272 lto_symtab_encoder_iterator lsei;
5273 lto_symtab_encoder_t encoder;
5275 if (!ipa_node_params_sum || !ipa_edge_args_sum)
5276 return;
5278 ob = create_output_block (LTO_section_jump_functions);
5279 encoder = ob->decl_state->symtab_node_encoder;
5280 ob->symbol = NULL;
5281 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
5282 lsei_next_function_in_partition (&lsei))
5284 cgraph_node *node = lsei_cgraph_node (lsei);
5285 if (node->has_gimple_body_p ()
5286 && ipa_node_params_sum->get (node) != NULL)
5287 count++;
5290 streamer_write_uhwi (ob, count);
5292 /* Process all of the functions. */
5293 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
5294 lsei_next_function_in_partition (&lsei))
5296 cgraph_node *node = lsei_cgraph_node (lsei);
5297 if (node->has_gimple_body_p ()
5298 && ipa_node_params_sum->get (node) != NULL)
5299 ipa_write_node_info (ob, node);
5301 streamer_write_char_stream (ob->main_stream, 0);
5302 produce_asm (ob, NULL);
5303 destroy_output_block (ob);
5306 /* Read section in file FILE_DATA of length LEN with data DATA. */
5308 static void
5309 ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
5310 size_t len)
5312 const struct lto_function_header *header =
5313 (const struct lto_function_header *) data;
5314 const int cfg_offset = sizeof (struct lto_function_header);
5315 const int main_offset = cfg_offset + header->cfg_size;
5316 const int string_offset = main_offset + header->main_size;
5317 class data_in *data_in;
5318 unsigned int i;
5319 unsigned int count;
5321 lto_input_block ib_main ((const char *) data + main_offset,
5322 header->main_size, file_data);
5324 data_in =
5325 lto_data_in_create (file_data, (const char *) data + string_offset,
5326 header->string_size, vNULL);
5327 count = streamer_read_uhwi (&ib_main);
5329 for (i = 0; i < count; i++)
5331 unsigned int index;
5332 struct cgraph_node *node;
5333 lto_symtab_encoder_t encoder;
5335 index = streamer_read_uhwi (&ib_main);
5336 encoder = file_data->symtab_node_encoder;
5337 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
5338 index));
5339 gcc_assert (node->definition);
5340 ipa_read_node_info (&ib_main, node, data_in);
5342 lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
5343 len);
5344 lto_data_in_delete (data_in);
5347 /* Read ipcp jump functions. */
5349 void
5350 ipa_prop_read_jump_functions (void)
5352 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
5353 struct lto_file_decl_data *file_data;
5354 unsigned int j = 0;
5356 ipa_check_create_node_params ();
5357 ipa_check_create_edge_args ();
5358 ipa_register_cgraph_hooks ();
5360 while ((file_data = file_data_vec[j++]))
5362 size_t len;
5363 const char *data
5364 = lto_get_summary_section_data (file_data, LTO_section_jump_functions,
5365 &len);
5366 if (data)
5367 ipa_prop_read_section (file_data, data, len);
5371 /* Return true if the IPA-CP transformation summary TS is non-NULL and contains
5372 useful info. */
5373 static bool
5374 useful_ipcp_transformation_info_p (ipcp_transformation *ts)
5376 if (!ts)
5377 return false;
5378 if (!vec_safe_is_empty (ts->m_agg_values)
5379 || !vec_safe_is_empty (ts->m_vr))
5380 return true;
5381 return false;
5384 /* Write into OB IPA-CP transfromation summary TS describing NODE. */
5386 void
5387 write_ipcp_transformation_info (output_block *ob, cgraph_node *node,
5388 ipcp_transformation *ts)
5390 lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
5391 int node_ref = lto_symtab_encoder_encode (encoder, node);
5392 streamer_write_uhwi (ob, node_ref);
5394 streamer_write_uhwi (ob, vec_safe_length (ts->m_agg_values));
5395 for (const ipa_argagg_value &av : ts->m_agg_values)
5397 struct bitpack_d bp;
5399 stream_write_tree (ob, av.value, true);
5400 streamer_write_uhwi (ob, av.unit_offset);
5401 streamer_write_uhwi (ob, av.index);
5403 bp = bitpack_create (ob->main_stream);
5404 bp_pack_value (&bp, av.by_ref, 1);
5405 bp_pack_value (&bp, av.killed, 1);
5406 streamer_write_bitpack (&bp);
5409 streamer_write_uhwi (ob, vec_safe_length (ts->m_vr));
5410 for (const ipa_vr &parm_vr : ts->m_vr)
5411 parm_vr.streamer_write (ob);
5414 /* Stream in the aggregate value replacement chain for NODE from IB. */
5416 static void
5417 read_ipcp_transformation_info (lto_input_block *ib, cgraph_node *node,
5418 data_in *data_in)
5420 unsigned int count, i;
5421 ipcp_transformation_initialize ();
5422 ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
5424 count = streamer_read_uhwi (ib);
5425 if (count > 0)
5427 vec_safe_grow_cleared (ts->m_agg_values, count, true);
5428 for (i = 0; i <count; i++)
5430 ipa_argagg_value *av = &(*ts->m_agg_values)[i];;
5432 av->value = stream_read_tree (ib, data_in);
5433 av->unit_offset = streamer_read_uhwi (ib);
5434 av->index = streamer_read_uhwi (ib);
5436 bitpack_d bp = streamer_read_bitpack (ib);
5437 av->by_ref = bp_unpack_value (&bp, 1);
5438 av->killed = bp_unpack_value (&bp, 1);
5442 count = streamer_read_uhwi (ib);
5443 if (count > 0)
5445 vec_safe_grow_cleared (ts->m_vr, count, true);
5446 for (i = 0; i < count; i++)
5448 ipa_vr *parm_vr;
5449 parm_vr = &(*ts->m_vr)[i];
5450 parm_vr->streamer_read (ib, data_in);
5455 /* Write all aggregate replacement for nodes in set. */
5457 void
5458 ipcp_write_transformation_summaries (void)
5460 struct output_block *ob;
5461 unsigned int count = 0;
5462 lto_symtab_encoder_t encoder;
5464 ob = create_output_block (LTO_section_ipcp_transform);
5465 encoder = ob->decl_state->symtab_node_encoder;
5466 ob->symbol = NULL;
5468 for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
5470 symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
5471 cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
5472 if (!cnode)
5473 continue;
5474 ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
5475 if (useful_ipcp_transformation_info_p (ts)
5476 && lto_symtab_encoder_encode_body_p (encoder, cnode))
5477 count++;
5480 streamer_write_uhwi (ob, count);
5482 for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
5484 symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
5485 cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
5486 if (!cnode)
5487 continue;
5488 ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
5489 if (useful_ipcp_transformation_info_p (ts)
5490 && lto_symtab_encoder_encode_body_p (encoder, cnode))
5491 write_ipcp_transformation_info (ob, cnode, ts);
5493 streamer_write_char_stream (ob->main_stream, 0);
5494 produce_asm (ob, NULL);
5495 destroy_output_block (ob);
5498 /* Read replacements section in file FILE_DATA of length LEN with data
5499 DATA. */
5501 static void
5502 read_replacements_section (struct lto_file_decl_data *file_data,
5503 const char *data,
5504 size_t len)
5506 const struct lto_function_header *header =
5507 (const struct lto_function_header *) data;
5508 const int cfg_offset = sizeof (struct lto_function_header);
5509 const int main_offset = cfg_offset + header->cfg_size;
5510 const int string_offset = main_offset + header->main_size;
5511 class data_in *data_in;
5512 unsigned int i;
5513 unsigned int count;
5515 lto_input_block ib_main ((const char *) data + main_offset,
5516 header->main_size, file_data);
5518 data_in = lto_data_in_create (file_data, (const char *) data + string_offset,
5519 header->string_size, vNULL);
5520 count = streamer_read_uhwi (&ib_main);
5522 for (i = 0; i < count; i++)
5524 unsigned int index;
5525 struct cgraph_node *node;
5526 lto_symtab_encoder_t encoder;
5528 index = streamer_read_uhwi (&ib_main);
5529 encoder = file_data->symtab_node_encoder;
5530 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
5531 index));
5532 read_ipcp_transformation_info (&ib_main, node, data_in);
5534 lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
5535 len);
5536 lto_data_in_delete (data_in);
5539 /* Read IPA-CP aggregate replacements. */
5541 void
5542 ipcp_read_transformation_summaries (void)
5544 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
5545 struct lto_file_decl_data *file_data;
5546 unsigned int j = 0;
5548 while ((file_data = file_data_vec[j++]))
5550 size_t len;
5551 const char *data
5552 = lto_get_summary_section_data (file_data, LTO_section_ipcp_transform,
5553 &len);
5554 if (data)
5555 read_replacements_section (file_data, data, len);
5559 /* Adjust the aggregate replacements in TS to reflect any parameter removals
5560 which might have already taken place. If after adjustments there are no
5561 aggregate replacements left, the m_agg_values will be set to NULL. In other
5562 cases, it may be shrunk. */
5564 static void
5565 adjust_agg_replacement_values (cgraph_node *node, ipcp_transformation *ts)
5567 clone_info *cinfo = clone_info::get (node);
5568 if (!cinfo || !cinfo->param_adjustments)
5569 return;
5571 auto_vec<int, 16> new_indices;
5572 cinfo->param_adjustments->get_updated_indices (&new_indices);
5573 bool removed_item = false;
5574 unsigned dst_index = 0;
5575 unsigned count = ts->m_agg_values->length ();
5576 for (unsigned i = 0; i < count; i++)
5578 ipa_argagg_value *v = &(*ts->m_agg_values)[i];
5579 gcc_checking_assert (v->index >= 0);
5581 int new_idx = -1;
5582 if ((unsigned) v->index < new_indices.length ())
5583 new_idx = new_indices[v->index];
5585 if (new_idx >= 0)
5587 v->index = new_idx;
5588 if (removed_item)
5589 (*ts->m_agg_values)[dst_index] = *v;
5590 dst_index++;
5592 else
5593 removed_item = true;
5596 if (dst_index == 0)
5598 ggc_free (ts->m_agg_values);
5599 ts->m_agg_values = NULL;
5601 else if (removed_item)
5602 ts->m_agg_values->truncate (dst_index);
5604 return;
5607 /* Dominator walker driving the ipcp modification phase. */
5609 class ipcp_modif_dom_walker : public dom_walker
5611 public:
5612 ipcp_modif_dom_walker (struct ipa_func_body_info *fbi,
5613 vec<ipa_param_descriptor, va_gc> *descs,
5614 ipcp_transformation *ts, bool *sc)
5615 : dom_walker (CDI_DOMINATORS), m_fbi (fbi), m_descriptors (descs),
5616 m_ts (ts), m_something_changed (sc) {}
5618 edge before_dom_children (basic_block) final override;
5619 bool cleanup_eh ()
5620 { return gimple_purge_all_dead_eh_edges (m_need_eh_cleanup); }
5622 private:
5623 struct ipa_func_body_info *m_fbi;
5624 vec<ipa_param_descriptor, va_gc> *m_descriptors;
5625 ipcp_transformation *m_ts;
5626 bool *m_something_changed;
5627 auto_bitmap m_need_eh_cleanup;
5630 edge
5631 ipcp_modif_dom_walker::before_dom_children (basic_block bb)
5633 gimple_stmt_iterator gsi;
5634 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
5636 gimple *stmt = gsi_stmt (gsi);
5637 tree rhs, val, t;
5638 HOST_WIDE_INT bit_offset;
5639 poly_int64 size;
5640 int index;
5641 bool by_ref, vce;
5643 if (!gimple_assign_load_p (stmt))
5644 continue;
5645 rhs = gimple_assign_rhs1 (stmt);
5646 if (!is_gimple_reg_type (TREE_TYPE (rhs)))
5647 continue;
5649 vce = false;
5650 t = rhs;
5651 while (handled_component_p (t))
5653 /* V_C_E can do things like convert an array of integers to one
5654 bigger integer and similar things we do not handle below. */
5655 if (TREE_CODE (t) == VIEW_CONVERT_EXPR)
5657 vce = true;
5658 break;
5660 t = TREE_OPERAND (t, 0);
5662 if (vce)
5663 continue;
5665 if (!ipa_load_from_parm_agg (m_fbi, m_descriptors, stmt, rhs, &index,
5666 &bit_offset, &size, &by_ref))
5667 continue;
5668 unsigned unit_offset = bit_offset / BITS_PER_UNIT;
5669 ipa_argagg_value_list avl (m_ts);
5670 tree v = avl.get_value (index, unit_offset, by_ref);
5672 if (!v
5673 || maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (v))), size))
5674 continue;
5676 gcc_checking_assert (is_gimple_ip_invariant (v));
5677 if (!useless_type_conversion_p (TREE_TYPE (rhs), TREE_TYPE (v)))
5679 if (fold_convertible_p (TREE_TYPE (rhs), v))
5680 val = fold_build1 (NOP_EXPR, TREE_TYPE (rhs), v);
5681 else if (TYPE_SIZE (TREE_TYPE (rhs))
5682 == TYPE_SIZE (TREE_TYPE (v)))
5683 val = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (rhs), v);
5684 else
5686 if (dump_file)
5688 fprintf (dump_file, " const ");
5689 print_generic_expr (dump_file, v);
5690 fprintf (dump_file, " can't be converted to type of ");
5691 print_generic_expr (dump_file, rhs);
5692 fprintf (dump_file, "\n");
5694 continue;
5697 else
5698 val = v;
5700 if (dump_file && (dump_flags & TDF_DETAILS))
5702 fprintf (dump_file, "Modifying stmt:\n ");
5703 print_gimple_stmt (dump_file, stmt, 0);
5705 gimple_assign_set_rhs_from_tree (&gsi, val);
5706 update_stmt (stmt);
5708 if (dump_file && (dump_flags & TDF_DETAILS))
5710 fprintf (dump_file, "into:\n ");
5711 print_gimple_stmt (dump_file, stmt, 0);
5712 fprintf (dump_file, "\n");
5715 *m_something_changed = true;
5716 if (maybe_clean_eh_stmt (stmt))
5717 bitmap_set_bit (m_need_eh_cleanup, bb->index);
5719 return NULL;
5722 /* If IPA-CP discovered a constant in parameter PARM at OFFSET of a given SIZE
5723 - whether passed by reference or not is given by BY_REF - return that
5724 constant. Otherwise return NULL_TREE. The is supposed to be used only
5725 after clone materialization and transformation is done (because it asserts
5726 that killed constants have been pruned). */
5728 tree
5729 ipcp_get_aggregate_const (struct function *func, tree parm, bool by_ref,
5730 HOST_WIDE_INT bit_offset, HOST_WIDE_INT bit_size)
5732 cgraph_node *node = cgraph_node::get (func->decl);
5733 ipcp_transformation *ts = ipcp_get_transformation_summary (node);
5735 if (!ts || !ts->m_agg_values)
5736 return NULL_TREE;
5738 int index = ts->get_param_index (func->decl, parm);
5739 if (index < 0)
5740 return NULL_TREE;
5742 ipa_argagg_value_list avl (ts);
5743 unsigned unit_offset = bit_offset / BITS_PER_UNIT;
5744 const ipa_argagg_value *av = avl.get_elt (index, unit_offset);
5745 if (!av || av->by_ref != by_ref)
5746 return NULL_TREE;
5747 gcc_assert (!av->killed);
5748 tree v = av->value;
5749 if (!v
5750 || maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (v))), bit_size))
5751 return NULL_TREE;
5753 return v;
5756 /* Return true if we have recorded VALUE and MASK about PARM.
5757 Set VALUE and MASk accordingly. */
5759 bool
5760 ipcp_get_parm_bits (tree parm, tree *value, widest_int *mask)
5762 cgraph_node *cnode = cgraph_node::get (current_function_decl);
5763 ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
5764 if (!ts
5765 || vec_safe_length (ts->m_vr) == 0
5766 || !irange::supports_p (TREE_TYPE (parm)))
5767 return false;
5769 int i = ts->get_param_index (current_function_decl, parm);
5770 if (i < 0)
5771 return false;
5772 clone_info *cinfo = clone_info::get (cnode);
5773 if (cinfo && cinfo->param_adjustments)
5775 i = cinfo->param_adjustments->get_original_index (i);
5776 if (i < 0)
5777 return false;
5780 vec<ipa_vr, va_gc> &vr = *ts->m_vr;
5781 if (!vr[i].known_p ())
5782 return false;
5783 Value_Range tmp;
5784 vr[i].get_vrange (tmp);
5785 if (tmp.undefined_p () || tmp.varying_p ())
5786 return false;
5787 irange_bitmask bm;
5788 bm = tmp.get_bitmask ();
5789 *mask = widest_int::from (bm.mask (), TYPE_SIGN (TREE_TYPE (parm)));
5790 *value = wide_int_to_tree (TREE_TYPE (parm), bm.value ());
5791 return true;
5794 /* Update value range of formal parameters of NODE as described in TS. */
5796 static void
5797 ipcp_update_vr (struct cgraph_node *node, ipcp_transformation *ts)
5799 if (vec_safe_is_empty (ts->m_vr))
5800 return;
5801 const vec<ipa_vr, va_gc> &vr = *ts->m_vr;
5802 unsigned count = vr.length ();
5803 if (!count)
5804 return;
5806 auto_vec<int, 16> new_indices;
5807 bool need_remapping = false;
5808 clone_info *cinfo = clone_info::get (node);
5809 if (cinfo && cinfo->param_adjustments)
5811 cinfo->param_adjustments->get_updated_indices (&new_indices);
5812 need_remapping = true;
5814 auto_vec <tree, 16> parm_decls;
5815 push_function_arg_decls (&parm_decls, node->decl);
5817 for (unsigned i = 0; i < count; ++i)
5819 tree parm;
5820 int remapped_idx;
5821 if (need_remapping)
5823 if (i >= new_indices.length ())
5824 continue;
5825 remapped_idx = new_indices[i];
5826 if (remapped_idx < 0)
5827 continue;
5829 else
5830 remapped_idx = i;
5832 parm = parm_decls[remapped_idx];
5834 gcc_checking_assert (parm);
5835 tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl), parm);
5837 if (!ddef || !is_gimple_reg (parm))
5838 continue;
5840 if (vr[i].known_p ())
5842 Value_Range tmp;
5843 vr[i].get_vrange (tmp);
5845 if (!tmp.undefined_p () && !tmp.varying_p ())
5847 if (dump_file)
5849 fprintf (dump_file, "Setting value range of param %u "
5850 "(now %i) ", i, remapped_idx);
5851 tmp.dump (dump_file);
5852 fprintf (dump_file, "]\n");
5854 set_range_info (ddef, tmp);
5856 if (POINTER_TYPE_P (TREE_TYPE (parm))
5857 && opt_for_fn (node->decl, flag_ipa_bit_cp))
5859 irange_bitmask bm = tmp.get_bitmask ();
5860 unsigned tem = bm.mask ().to_uhwi ();
5861 unsigned HOST_WIDE_INT bitpos = bm.value ().to_uhwi ();
5862 unsigned align = tem & -tem;
5863 unsigned misalign = bitpos & (align - 1);
5865 if (align > 1)
5867 if (dump_file)
5869 fprintf (dump_file,
5870 "Adjusting mask for param %u to ", i);
5871 print_hex (bm.mask (), dump_file);
5872 fprintf (dump_file, "\n");
5875 if (dump_file)
5876 fprintf (dump_file,
5877 "Adjusting align: %u, misalign: %u\n",
5878 align, misalign);
5880 unsigned old_align, old_misalign;
5881 struct ptr_info_def *pi = get_ptr_info (ddef);
5882 bool old_known = get_ptr_info_alignment (pi, &old_align,
5883 &old_misalign);
5885 if (old_known && old_align > align)
5887 if (dump_file)
5889 fprintf (dump_file,
5890 "But alignment was already %u.\n",
5891 old_align);
5892 if ((old_misalign & (align - 1)) != misalign)
5893 fprintf (dump_file,
5894 "old_misalign (%u) and misalign "
5895 "(%u) mismatch\n",
5896 old_misalign, misalign);
5898 continue;
5901 if (dump_file
5902 && old_known
5903 && ((misalign & (old_align - 1)) != old_misalign))
5904 fprintf (dump_file,
5905 "old_misalign (%u) and misalign (%u) "
5906 "mismatch\n",
5907 old_misalign, misalign);
5909 set_ptr_info_alignment (pi, align, misalign);
5912 else if (dump_file && INTEGRAL_TYPE_P (TREE_TYPE (parm)))
5914 irange &r = as_a<irange> (tmp);
5915 irange_bitmask bm = r.get_bitmask ();
5916 unsigned prec = TYPE_PRECISION (TREE_TYPE (parm));
5917 if (wi::ne_p (bm.mask (), wi::shwi (-1, prec)))
5919 fprintf (dump_file,
5920 "Adjusting mask for param %u to ", i);
5921 print_hex (bm.mask (), dump_file);
5922 fprintf (dump_file, "\n");
5930 /* IPCP transformation phase doing propagation of aggregate values. */
5932 unsigned int
5933 ipcp_transform_function (struct cgraph_node *node)
5935 struct ipa_func_body_info fbi;
5936 int param_count;
5938 gcc_checking_assert (cfun);
5939 gcc_checking_assert (current_function_decl);
5941 if (dump_file)
5942 fprintf (dump_file, "Modification phase of node %s\n",
5943 node->dump_name ());
5945 ipcp_transformation *ts = ipcp_get_transformation_summary (node);
5946 if (!ts
5947 || (vec_safe_is_empty (ts->m_agg_values)
5948 && vec_safe_is_empty (ts->m_vr)))
5949 return 0;
5951 ts->maybe_create_parm_idx_map (cfun->decl);
5952 ipcp_update_vr (node, ts);
5953 if (vec_safe_is_empty (ts->m_agg_values))
5954 return 0;
5955 param_count = count_formal_params (node->decl);
5956 if (param_count == 0)
5957 return 0;
5959 adjust_agg_replacement_values (node, ts);
5960 if (vec_safe_is_empty (ts->m_agg_values))
5962 if (dump_file)
5963 fprintf (dump_file, " All affected aggregate parameters were either "
5964 "removed or converted into scalars, phase done.\n");
5965 return 0;
5967 if (dump_file)
5969 fprintf (dump_file, " Aggregate replacements:");
5970 ipa_argagg_value_list avs (ts);
5971 avs.dump (dump_file);
5974 fbi.node = node;
5975 fbi.info = NULL;
5976 fbi.bb_infos = vNULL;
5977 fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
5978 fbi.param_count = param_count;
5979 fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps);
5981 vec<ipa_param_descriptor, va_gc> *descriptors = NULL;
5982 vec_safe_grow_cleared (descriptors, param_count, true);
5983 ipa_populate_param_decls (node, *descriptors);
5984 bool modified_mem_access = false;
5985 calculate_dominance_info (CDI_DOMINATORS);
5986 ipcp_modif_dom_walker walker (&fbi, descriptors, ts, &modified_mem_access);
5987 walker.walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
5988 free_dominance_info (CDI_DOMINATORS);
5989 bool cfg_changed = walker.cleanup_eh ();
5991 int i;
5992 struct ipa_bb_info *bi;
5993 FOR_EACH_VEC_ELT (fbi.bb_infos, i, bi)
5994 free_ipa_bb_info (bi);
5995 fbi.bb_infos.release ();
5997 ts->remove_argaggs_if ([](const ipa_argagg_value &v)
5999 return v.killed;
6002 vec_free (descriptors);
6003 if (cfg_changed)
6004 delete_unreachable_blocks_update_callgraph (node, false);
6006 return modified_mem_access ? TODO_update_ssa_only_virtuals : 0;
6009 /* Record that current function return value range is VAL. */
6011 void
6012 ipa_record_return_value_range (Value_Range val)
6014 cgraph_node *n = cgraph_node::get (current_function_decl);
6015 if (!ipa_return_value_sum)
6017 if (!ipa_vr_hash_table)
6018 ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
6019 ipa_return_value_sum = new (ggc_alloc_no_dtor <ipa_return_value_sum_t> ())
6020 ipa_return_value_sum_t (symtab, true);
6021 ipa_return_value_sum->disable_insertion_hook ();
6023 ipa_return_value_sum->get_create (n)->vr = ipa_get_value_range (val);
6024 if (dump_file && (dump_flags & TDF_DETAILS))
6026 fprintf (dump_file, "Recording return range ");
6027 val.dump (dump_file);
6028 fprintf (dump_file, "\n");
6032 /* Return true if value range of DECL is known and if so initialize RANGE. */
6034 bool
6035 ipa_return_value_range (Value_Range &range, tree decl)
6037 cgraph_node *n = cgraph_node::get (decl);
6038 if (!n || !ipa_return_value_sum)
6039 return false;
6040 enum availability avail;
6041 n = n->ultimate_alias_target (&avail);
6042 if (avail < AVAIL_AVAILABLE)
6043 return false;
6044 if (n->decl != decl && !useless_type_conversion_p (TREE_TYPE (decl), TREE_TYPE (n->decl)))
6045 return false;
6046 ipa_return_value_summary *v = ipa_return_value_sum->get (n);
6047 if (!v)
6048 return false;
6049 v->vr->get_vrange (range);
6050 return true;
6053 /* Reset all state within ipa-prop.cc so that we can rerun the compiler
6054 within the same process. For use by toplev::finalize. */
6056 void
6057 ipa_prop_cc_finalize (void)
6059 if (function_insertion_hook_holder)
6060 symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
6061 function_insertion_hook_holder = NULL;
6063 if (ipa_edge_args_sum)
6064 ggc_delete (ipa_edge_args_sum);
6065 ipa_edge_args_sum = NULL;
6067 if (ipa_node_params_sum)
6068 ggc_delete (ipa_node_params_sum);
6069 ipa_node_params_sum = NULL;
6072 /* Return true if the two pass_through components of two jump functions are
6073 known to be equivalent. AGG_JF denotes whether they are part of aggregate
6074 functions or not. The function can be used before the IPA phase of IPA-CP
6075 or inlining because it cannot cope with refdesc changes these passes can
6076 carry out. */
6078 static bool
6079 ipa_agg_pass_through_jf_equivalent_p (ipa_pass_through_data *ipt1,
6080 ipa_pass_through_data *ipt2,
6081 bool agg_jf)
6084 gcc_assert (agg_jf ||
6085 (!ipt1->refdesc_decremented && !ipt2->refdesc_decremented));
6086 if (ipt1->operation != ipt2->operation
6087 || ipt1->formal_id != ipt2->formal_id
6088 || (!agg_jf && (ipt1->agg_preserved != ipt2->agg_preserved)))
6089 return false;
6090 if (((ipt1->operand != NULL_TREE) != (ipt2->operand != NULL_TREE))
6091 || (ipt1->operand
6092 && !values_equal_for_ipcp_p (ipt1->operand, ipt2->operand)))
6093 return false;
6094 return true;
6097 /* Return true if the two aggregate jump functions are known to be equivalent.
6098 The function can be used before the IPA phase of IPA-CP or inlining because
6099 it cannot cope with refdesc changes these passes can carry out. */
6101 static bool
6102 ipa_agg_jump_functions_equivalent_p (ipa_agg_jf_item *ajf1,
6103 ipa_agg_jf_item *ajf2)
6105 if (ajf1->offset != ajf2->offset
6106 || ajf1->jftype != ajf2->jftype
6107 || !types_compatible_p (ajf1->type, ajf2->type))
6108 return false;
6110 switch (ajf1->jftype)
6112 case IPA_JF_CONST:
6113 if (!values_equal_for_ipcp_p (ajf1->value.constant,
6114 ajf2->value.constant))
6115 return false;
6116 break;
6117 case IPA_JF_PASS_THROUGH:
6119 ipa_pass_through_data *ipt1 = &ajf1->value.pass_through;
6120 ipa_pass_through_data *ipt2 = &ajf2->value.pass_through;
6121 if (!ipa_agg_pass_through_jf_equivalent_p (ipt1, ipt2, true))
6122 return false;
6124 break;
6125 case IPA_JF_LOAD_AGG:
6127 ipa_load_agg_data *ila1 = &ajf1->value.load_agg;
6128 ipa_load_agg_data *ila2 = &ajf2->value.load_agg;
6129 if (!ipa_agg_pass_through_jf_equivalent_p (&ila1->pass_through,
6130 &ila2->pass_through, true))
6131 return false;
6132 if (ila1->offset != ila2->offset
6133 || ila1->by_ref != ila2->by_ref
6134 || !types_compatible_p (ila1->type, ila2->type))
6135 return false;
6137 break;
6138 default:
6139 gcc_unreachable ();
6141 return true;
6144 /* Return true if the two jump functions are known to be equivalent. The
6145 function can be used before the IPA phase of IPA-CP or inlining because it
6146 cannot cope with refdesc changes these passes can carry out. */
6148 bool
6149 ipa_jump_functions_equivalent_p (ipa_jump_func *jf1, ipa_jump_func *jf2)
6151 if (jf1->type != jf2->type)
6152 return false;
6154 switch (jf1->type)
6156 case IPA_JF_UNKNOWN:
6157 break;
6158 case IPA_JF_CONST:
6160 tree cst1 = ipa_get_jf_constant (jf1);
6161 tree cst2 = ipa_get_jf_constant (jf2);
6162 if (!values_equal_for_ipcp_p (cst1, cst2))
6163 return false;
6165 ipa_cst_ref_desc *rd1 = jfunc_rdesc_usable (jf1);
6166 ipa_cst_ref_desc *rd2 = jfunc_rdesc_usable (jf2);
6167 if (rd1 && rd2)
6169 gcc_assert (rd1->refcount == 1
6170 && rd2->refcount == 1);
6171 gcc_assert (!rd1->next_duplicate && !rd2->next_duplicate);
6173 else if (rd1)
6174 return false;
6175 else if (rd2)
6176 return false;
6178 break;
6179 case IPA_JF_PASS_THROUGH:
6181 ipa_pass_through_data *ipt1 = &jf1->value.pass_through;
6182 ipa_pass_through_data *ipt2 = &jf2->value.pass_through;
6183 if (!ipa_agg_pass_through_jf_equivalent_p (ipt1, ipt2, false))
6184 return false;
6186 break;
6187 case IPA_JF_ANCESTOR:
6189 ipa_ancestor_jf_data *ia1 = &jf1->value.ancestor;
6190 ipa_ancestor_jf_data *ia2 = &jf2->value.ancestor;
6192 if (ia1->formal_id != ia2->formal_id
6193 || ia1->agg_preserved != ia2->agg_preserved
6194 || ia1->keep_null != ia2->keep_null
6195 || ia1->offset != ia2->offset)
6196 return false;
6198 break;
6199 default:
6200 gcc_unreachable ();
6203 if (((jf1->m_vr != nullptr) != (jf2->m_vr != nullptr))
6204 || (jf1->m_vr && !jf1->m_vr->equal_p (*jf2->m_vr)))
6205 return false;
6207 unsigned alen = vec_safe_length (jf1->agg.items);
6208 if (vec_safe_length (jf2->agg.items) != alen)
6209 return false;
6211 if (!alen)
6212 return true;
6214 if (jf1->agg.by_ref != jf2->agg.by_ref)
6215 return false;
6217 for (unsigned i = 0 ; i < alen; i++)
6218 if (!ipa_agg_jump_functions_equivalent_p (&(*jf1->agg.items)[i],
6219 &(*jf2->agg.items)[i]))
6220 return false;
6222 return true;
6225 #include "gt-ipa-prop.h"