d: Add testcase from PR108962
[official-gcc.git] / gcc / ipa-prop.cc
blob33bda8288fc7d600b2e0d1b478697b3877dd2985
1 /* Interprocedural analyses.
2 Copyright (C) 2005-2023 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "backend.h"
24 #include "rtl.h"
25 #include "tree.h"
26 #include "gimple.h"
27 #include "alloc-pool.h"
28 #include "tree-pass.h"
29 #include "ssa.h"
30 #include "tree-streamer.h"
31 #include "cgraph.h"
32 #include "diagnostic.h"
33 #include "fold-const.h"
34 #include "gimple-iterator.h"
35 #include "gimple-fold.h"
36 #include "tree-eh.h"
37 #include "calls.h"
38 #include "stor-layout.h"
39 #include "print-tree.h"
40 #include "gimplify.h"
41 #include "gimplify-me.h"
42 #include "gimple-walk.h"
43 #include "symbol-summary.h"
44 #include "ipa-prop.h"
45 #include "tree-cfg.h"
46 #include "tree-dfa.h"
47 #include "tree-inline.h"
48 #include "ipa-fnsummary.h"
49 #include "gimple-pretty-print.h"
50 #include "ipa-utils.h"
51 #include "dbgcnt.h"
52 #include "domwalk.h"
53 #include "builtins.h"
54 #include "tree-cfgcleanup.h"
55 #include "options.h"
56 #include "symtab-clones.h"
57 #include "attr-fnspec.h"
58 #include "gimple-range.h"
59 #include "value-range-storage.h"
61 /* Function summary where the parameter infos are actually stored. */
62 ipa_node_params_t *ipa_node_params_sum = NULL;
64 function_summary <ipcp_transformation *> *ipcp_transformation_sum = NULL;
66 /* Edge summary for IPA-CP edge information. */
67 ipa_edge_args_sum_t *ipa_edge_args_sum;
69 /* Traits for a hash table for reusing already existing ipa_bits. */
71 struct ipa_bit_ggc_hash_traits : public ggc_cache_remove <ipa_bits *>
73 typedef ipa_bits *value_type;
74 typedef ipa_bits *compare_type;
75 static hashval_t
76 hash (const ipa_bits *p)
78 hashval_t t = (hashval_t) p->value.to_shwi ();
79 return iterative_hash_host_wide_int (p->mask.to_shwi (), t);
81 static bool
82 equal (const ipa_bits *a, const ipa_bits *b)
84 return a->value == b->value && a->mask == b->mask;
86 static const bool empty_zero_p = true;
87 static void
88 mark_empty (ipa_bits *&p)
90 p = NULL;
92 static bool
93 is_empty (const ipa_bits *p)
95 return p == NULL;
97 static bool
98 is_deleted (const ipa_bits *p)
100 return p == reinterpret_cast<const ipa_bits *> (1);
102 static void
103 mark_deleted (ipa_bits *&p)
105 p = reinterpret_cast<ipa_bits *> (1);
109 /* Hash table for avoid repeated allocations of equal ipa_bits. */
110 static GTY ((cache)) hash_table<ipa_bit_ggc_hash_traits> *ipa_bits_hash_table;
112 /* Traits for a hash table for reusing ranges. */
114 struct ipa_vr_ggc_hash_traits : public ggc_cache_remove <ipa_vr *>
116 typedef ipa_vr *value_type;
117 typedef const vrange *compare_type;
118 static hashval_t
119 hash (const ipa_vr *p)
121 // This never get called, except in the verification code, as
122 // ipa_get_value_range() calculates the hash itself. This
123 // function is mostly here for completness' sake.
124 Value_Range vr;
125 p->get_vrange (vr);
126 inchash::hash hstate;
127 add_vrange (vr, hstate);
128 return hstate.end ();
130 static bool
131 equal (const ipa_vr *a, const vrange *b)
133 return a->equal_p (*b);
135 static const bool empty_zero_p = true;
136 static void
137 mark_empty (ipa_vr *&p)
139 p = NULL;
141 static bool
142 is_empty (const ipa_vr *p)
144 return p == NULL;
146 static bool
147 is_deleted (const ipa_vr *p)
149 return p == reinterpret_cast<const ipa_vr *> (1);
151 static void
152 mark_deleted (ipa_vr *&p)
154 p = reinterpret_cast<ipa_vr *> (1);
158 /* Hash table for avoid repeated allocations of equal ranges. */
159 static GTY ((cache)) hash_table<ipa_vr_ggc_hash_traits> *ipa_vr_hash_table;
161 /* Holders of ipa cgraph hooks: */
162 static struct cgraph_node_hook_list *function_insertion_hook_holder;
164 /* Description of a reference to an IPA constant. */
165 struct ipa_cst_ref_desc
167 /* Edge that corresponds to the statement which took the reference. */
168 struct cgraph_edge *cs;
169 /* Linked list of duplicates created when call graph edges are cloned. */
170 struct ipa_cst_ref_desc *next_duplicate;
171 /* Number of references in IPA structures, IPA_UNDESCRIBED_USE if the value
172 if out of control. */
173 int refcount;
176 /* Allocation pool for reference descriptions. */
178 static object_allocator<ipa_cst_ref_desc> ipa_refdesc_pool
179 ("IPA-PROP ref descriptions");
181 ipa_vr::ipa_vr ()
182 : m_storage (NULL),
183 m_type (NULL)
187 ipa_vr::ipa_vr (const vrange &r)
188 : m_storage (ggc_alloc_vrange_storage (r)),
189 m_type (r.type ())
193 bool
194 ipa_vr::equal_p (const vrange &r) const
196 gcc_checking_assert (!r.undefined_p ());
197 return (types_compatible_p (m_type, r.type ()) && m_storage->equal_p (r));
200 void
201 ipa_vr::get_vrange (Value_Range &r) const
203 r.set_type (m_type);
204 m_storage->get_vrange (r, m_type);
207 void
208 ipa_vr::set_unknown ()
210 if (m_storage)
211 ggc_free (m_storage);
213 m_storage = NULL;
216 void
217 ipa_vr::streamer_read (lto_input_block *ib, data_in *data_in)
219 struct bitpack_d bp = streamer_read_bitpack (ib);
220 bool known = bp_unpack_value (&bp, 1);
221 if (known)
223 Value_Range vr;
224 streamer_read_value_range (ib, data_in, vr);
225 if (!m_storage || !m_storage->fits_p (vr))
227 if (m_storage)
228 ggc_free (m_storage);
229 m_storage = ggc_alloc_vrange_storage (vr);
231 m_storage->set_vrange (vr);
232 m_type = vr.type ();
234 else
236 m_storage = NULL;
237 m_type = NULL;
241 void
242 ipa_vr::streamer_write (output_block *ob) const
244 struct bitpack_d bp = bitpack_create (ob->main_stream);
245 bp_pack_value (&bp, !!m_storage, 1);
246 streamer_write_bitpack (&bp);
247 if (m_storage)
249 Value_Range vr (m_type);
250 m_storage->get_vrange (vr, m_type);
251 streamer_write_vrange (ob, vr);
255 void
256 ipa_vr::dump (FILE *out) const
258 if (known_p ())
260 Value_Range vr (m_type);
261 m_storage->get_vrange (vr, m_type);
262 vr.dump (out);
264 else
265 fprintf (out, "NO RANGE");
268 // These stubs are because we use an ipa_vr in a hash_traits and
269 // hash-traits.h defines an extern of gt_ggc_mx (T &) instead of
270 // picking up the gt_ggc_mx (T *) version.
271 void
272 gt_pch_nx (ipa_vr *&x)
274 return gt_pch_nx ((ipa_vr *) x);
277 void
278 gt_ggc_mx (ipa_vr *&x)
280 return gt_ggc_mx ((ipa_vr *) x);
284 /* Return true if DECL_FUNCTION_SPECIFIC_OPTIMIZATION of the decl associated
285 with NODE should prevent us from analyzing it for the purposes of IPA-CP. */
287 static bool
288 ipa_func_spec_opts_forbid_analysis_p (struct cgraph_node *node)
290 tree fs_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (node->decl);
292 if (!fs_opts)
293 return false;
294 return !opt_for_fn (node->decl, optimize) || !opt_for_fn (node->decl, flag_ipa_cp);
297 /* Return index of the formal whose tree is PTREE in function which corresponds
298 to INFO. */
300 static int
301 ipa_get_param_decl_index_1 (vec<ipa_param_descriptor, va_gc> *descriptors,
302 tree ptree)
304 int i, count;
306 count = vec_safe_length (descriptors);
307 for (i = 0; i < count; i++)
308 if ((*descriptors)[i].decl_or_type == ptree)
309 return i;
311 return -1;
314 /* Return index of the formal whose tree is PTREE in function which corresponds
315 to INFO. */
318 ipa_get_param_decl_index (class ipa_node_params *info, tree ptree)
320 return ipa_get_param_decl_index_1 (info->descriptors, ptree);
323 /* Populate the param_decl field in parameter DESCRIPTORS that correspond to
324 NODE. */
326 static void
327 ipa_populate_param_decls (struct cgraph_node *node,
328 vec<ipa_param_descriptor, va_gc> &descriptors)
330 tree fndecl;
331 tree fnargs;
332 tree parm;
333 int param_num;
335 fndecl = node->decl;
336 gcc_assert (gimple_has_body_p (fndecl));
337 fnargs = DECL_ARGUMENTS (fndecl);
338 param_num = 0;
339 for (parm = fnargs; parm; parm = DECL_CHAIN (parm))
341 descriptors[param_num].decl_or_type = parm;
342 unsigned int cost = estimate_move_cost (TREE_TYPE (parm), true);
343 descriptors[param_num].move_cost = cost;
344 /* Watch overflow, move_cost is a bitfield. */
345 gcc_checking_assert (cost == descriptors[param_num].move_cost);
346 param_num++;
350 /* Return how many formal parameters FNDECL has. */
353 count_formal_params (tree fndecl)
355 tree parm;
356 int count = 0;
357 gcc_assert (gimple_has_body_p (fndecl));
359 for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
360 count++;
362 return count;
365 /* Return the declaration of Ith formal parameter of the function corresponding
366 to INFO. Note there is no setter function as this array is built just once
367 using ipa_initialize_node_params. */
369 void
370 ipa_dump_param (FILE *file, class ipa_node_params *info, int i)
372 fprintf (file, "param #%i", i);
373 if ((*info->descriptors)[i].decl_or_type)
375 fprintf (file, " ");
376 print_generic_expr (file, (*info->descriptors)[i].decl_or_type);
380 /* If necessary, allocate vector of parameter descriptors in info of NODE.
381 Return true if they were allocated, false if not. */
383 static bool
384 ipa_alloc_node_params (struct cgraph_node *node, int param_count)
386 ipa_node_params *info = ipa_node_params_sum->get_create (node);
388 if (!info->descriptors && param_count)
390 vec_safe_grow_cleared (info->descriptors, param_count, true);
391 return true;
393 else
394 return false;
397 /* Initialize the ipa_node_params structure associated with NODE by counting
398 the function parameters, creating the descriptors and populating their
399 param_decls. */
401 void
402 ipa_initialize_node_params (struct cgraph_node *node)
404 ipa_node_params *info = ipa_node_params_sum->get_create (node);
406 if (!info->descriptors
407 && ipa_alloc_node_params (node, count_formal_params (node->decl)))
408 ipa_populate_param_decls (node, *info->descriptors);
411 /* Print the jump functions associated with call graph edge CS to file F. */
413 static void
414 ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
416 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
417 int count = ipa_get_cs_argument_count (args);
419 for (int i = 0; i < count; i++)
421 struct ipa_jump_func *jump_func;
422 enum jump_func_type type;
424 jump_func = ipa_get_ith_jump_func (args, i);
425 type = jump_func->type;
427 fprintf (f, " param %d: ", i);
428 if (type == IPA_JF_UNKNOWN)
429 fprintf (f, "UNKNOWN\n");
430 else if (type == IPA_JF_CONST)
432 tree val = jump_func->value.constant.value;
433 fprintf (f, "CONST: ");
434 print_generic_expr (f, val);
435 if (TREE_CODE (val) == ADDR_EXPR
436 && TREE_CODE (TREE_OPERAND (val, 0)) == CONST_DECL)
438 fprintf (f, " -> ");
439 print_generic_expr (f, DECL_INITIAL (TREE_OPERAND (val, 0)));
441 fprintf (f, "\n");
443 else if (type == IPA_JF_PASS_THROUGH)
445 fprintf (f, "PASS THROUGH: ");
446 fprintf (f, "%d, op %s",
447 jump_func->value.pass_through.formal_id,
448 get_tree_code_name(jump_func->value.pass_through.operation));
449 if (jump_func->value.pass_through.operation != NOP_EXPR)
451 fprintf (f, " ");
452 print_generic_expr (f, jump_func->value.pass_through.operand);
454 if (jump_func->value.pass_through.agg_preserved)
455 fprintf (f, ", agg_preserved");
456 if (jump_func->value.pass_through.refdesc_decremented)
457 fprintf (f, ", refdesc_decremented");
458 fprintf (f, "\n");
460 else if (type == IPA_JF_ANCESTOR)
462 fprintf (f, "ANCESTOR: ");
463 fprintf (f, "%d, offset " HOST_WIDE_INT_PRINT_DEC,
464 jump_func->value.ancestor.formal_id,
465 jump_func->value.ancestor.offset);
466 if (jump_func->value.ancestor.agg_preserved)
467 fprintf (f, ", agg_preserved");
468 if (jump_func->value.ancestor.keep_null)
469 fprintf (f, ", keep_null");
470 fprintf (f, "\n");
473 if (jump_func->agg.items)
475 struct ipa_agg_jf_item *item;
476 int j;
478 fprintf (f, " Aggregate passed by %s:\n",
479 jump_func->agg.by_ref ? "reference" : "value");
480 FOR_EACH_VEC_ELT (*jump_func->agg.items, j, item)
482 fprintf (f, " offset: " HOST_WIDE_INT_PRINT_DEC ", ",
483 item->offset);
484 fprintf (f, "type: ");
485 print_generic_expr (f, item->type);
486 fprintf (f, ", ");
487 if (item->jftype == IPA_JF_PASS_THROUGH)
488 fprintf (f, "PASS THROUGH: %d,",
489 item->value.pass_through.formal_id);
490 else if (item->jftype == IPA_JF_LOAD_AGG)
492 fprintf (f, "LOAD AGG: %d",
493 item->value.pass_through.formal_id);
494 fprintf (f, " [offset: " HOST_WIDE_INT_PRINT_DEC ", by %s],",
495 item->value.load_agg.offset,
496 item->value.load_agg.by_ref ? "reference"
497 : "value");
500 if (item->jftype == IPA_JF_PASS_THROUGH
501 || item->jftype == IPA_JF_LOAD_AGG)
503 fprintf (f, " op %s",
504 get_tree_code_name (item->value.pass_through.operation));
505 if (item->value.pass_through.operation != NOP_EXPR)
507 fprintf (f, " ");
508 print_generic_expr (f, item->value.pass_through.operand);
511 else if (item->jftype == IPA_JF_CONST)
513 fprintf (f, "CONST: ");
514 print_generic_expr (f, item->value.constant);
516 else if (item->jftype == IPA_JF_UNKNOWN)
517 fprintf (f, "UNKNOWN: " HOST_WIDE_INT_PRINT_DEC " bits",
518 tree_to_uhwi (TYPE_SIZE (item->type)));
519 fprintf (f, "\n");
523 class ipa_polymorphic_call_context *ctx
524 = ipa_get_ith_polymorhic_call_context (args, i);
525 if (ctx && !ctx->useless_p ())
527 fprintf (f, " Context: ");
528 ctx->dump (dump_file);
531 if (jump_func->bits)
533 fprintf (f, " value: ");
534 print_hex (jump_func->bits->value, f);
535 fprintf (f, ", mask: ");
536 print_hex (jump_func->bits->mask, f);
537 fprintf (f, "\n");
539 else
540 fprintf (f, " Unknown bits\n");
542 if (jump_func->m_vr)
544 jump_func->m_vr->dump (f);
545 fprintf (f, "\n");
547 else
548 fprintf (f, " Unknown VR\n");
553 /* Print the jump functions of all arguments on all call graph edges going from
554 NODE to file F. */
556 void
557 ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
559 struct cgraph_edge *cs;
561 fprintf (f, " Jump functions of caller %s:\n", node->dump_name ());
562 for (cs = node->callees; cs; cs = cs->next_callee)
565 fprintf (f, " callsite %s -> %s : \n",
566 node->dump_name (),
567 cs->callee->dump_name ());
568 if (!ipa_edge_args_info_available_for_edge_p (cs))
569 fprintf (f, " no arg info\n");
570 else
571 ipa_print_node_jump_functions_for_edge (f, cs);
574 for (cs = node->indirect_calls; cs; cs = cs->next_callee)
576 class cgraph_indirect_call_info *ii;
578 ii = cs->indirect_info;
579 if (ii->agg_contents)
580 fprintf (f, " indirect %s callsite, calling param %i, "
581 "offset " HOST_WIDE_INT_PRINT_DEC ", %s",
582 ii->member_ptr ? "member ptr" : "aggregate",
583 ii->param_index, ii->offset,
584 ii->by_ref ? "by reference" : "by_value");
585 else
586 fprintf (f, " indirect %s callsite, calling param %i, "
587 "offset " HOST_WIDE_INT_PRINT_DEC,
588 ii->polymorphic ? "polymorphic" : "simple", ii->param_index,
589 ii->offset);
591 if (cs->call_stmt)
593 fprintf (f, ", for stmt ");
594 print_gimple_stmt (f, cs->call_stmt, 0, TDF_SLIM);
596 else
597 fprintf (f, "\n");
598 if (ii->polymorphic)
599 ii->context.dump (f);
600 if (!ipa_edge_args_info_available_for_edge_p (cs))
601 fprintf (f, " no arg info\n");
602 else
603 ipa_print_node_jump_functions_for_edge (f, cs);
607 /* Print ipa_jump_func data structures of all nodes in the call graph to F. */
609 void
610 ipa_print_all_jump_functions (FILE *f)
612 struct cgraph_node *node;
614 fprintf (f, "\nJump functions:\n");
615 FOR_EACH_FUNCTION (node)
617 ipa_print_node_jump_functions (f, node);
621 /* Set jfunc to be a know-really nothing jump function. */
623 static void
624 ipa_set_jf_unknown (struct ipa_jump_func *jfunc)
626 jfunc->type = IPA_JF_UNKNOWN;
629 /* Set JFUNC to be a copy of another jmp (to be used by jump function
630 combination code). The two functions will share their rdesc. */
632 static void
633 ipa_set_jf_cst_copy (struct ipa_jump_func *dst,
634 struct ipa_jump_func *src)
637 gcc_checking_assert (src->type == IPA_JF_CONST);
638 dst->type = IPA_JF_CONST;
639 dst->value.constant = src->value.constant;
642 /* Set JFUNC to be a constant jmp function. */
644 static void
645 ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
646 struct cgraph_edge *cs)
648 jfunc->type = IPA_JF_CONST;
649 jfunc->value.constant.value = unshare_expr_without_location (constant);
651 if (TREE_CODE (constant) == ADDR_EXPR
652 && (TREE_CODE (TREE_OPERAND (constant, 0)) == FUNCTION_DECL
653 || (VAR_P (TREE_OPERAND (constant, 0))
654 && TREE_STATIC (TREE_OPERAND (constant, 0)))))
656 struct ipa_cst_ref_desc *rdesc;
658 rdesc = ipa_refdesc_pool.allocate ();
659 rdesc->cs = cs;
660 rdesc->next_duplicate = NULL;
661 rdesc->refcount = 1;
662 jfunc->value.constant.rdesc = rdesc;
664 else
665 jfunc->value.constant.rdesc = NULL;
668 /* Set JFUNC to be a simple pass-through jump function. */
669 static void
670 ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
671 bool agg_preserved)
673 jfunc->type = IPA_JF_PASS_THROUGH;
674 jfunc->value.pass_through.operand = NULL_TREE;
675 jfunc->value.pass_through.formal_id = formal_id;
676 jfunc->value.pass_through.operation = NOP_EXPR;
677 jfunc->value.pass_through.agg_preserved = agg_preserved;
678 jfunc->value.pass_through.refdesc_decremented = false;
681 /* Set JFUNC to be an unary pass through jump function. */
683 static void
684 ipa_set_jf_unary_pass_through (struct ipa_jump_func *jfunc, int formal_id,
685 enum tree_code operation)
687 jfunc->type = IPA_JF_PASS_THROUGH;
688 jfunc->value.pass_through.operand = NULL_TREE;
689 jfunc->value.pass_through.formal_id = formal_id;
690 jfunc->value.pass_through.operation = operation;
691 jfunc->value.pass_through.agg_preserved = false;
692 jfunc->value.pass_through.refdesc_decremented = false;
694 /* Set JFUNC to be an arithmetic pass through jump function. */
696 static void
697 ipa_set_jf_arith_pass_through (struct ipa_jump_func *jfunc, int formal_id,
698 tree operand, enum tree_code operation)
700 jfunc->type = IPA_JF_PASS_THROUGH;
701 jfunc->value.pass_through.operand = unshare_expr_without_location (operand);
702 jfunc->value.pass_through.formal_id = formal_id;
703 jfunc->value.pass_through.operation = operation;
704 jfunc->value.pass_through.agg_preserved = false;
705 jfunc->value.pass_through.refdesc_decremented = false;
708 /* Set JFUNC to be an ancestor jump function. */
710 static void
711 ipa_set_ancestor_jf (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
712 int formal_id, bool agg_preserved, bool keep_null)
714 jfunc->type = IPA_JF_ANCESTOR;
715 jfunc->value.ancestor.formal_id = formal_id;
716 jfunc->value.ancestor.offset = offset;
717 jfunc->value.ancestor.agg_preserved = agg_preserved;
718 jfunc->value.ancestor.keep_null = keep_null;
721 /* Get IPA BB information about the given BB. FBI is the context of analyzis
722 of this function body. */
724 static struct ipa_bb_info *
725 ipa_get_bb_info (struct ipa_func_body_info *fbi, basic_block bb)
727 gcc_checking_assert (fbi);
728 return &fbi->bb_infos[bb->index];
731 /* Structure to be passed in between detect_type_change and
732 check_stmt_for_type_change. */
734 struct prop_type_change_info
736 /* Offset into the object where there is the virtual method pointer we are
737 looking for. */
738 HOST_WIDE_INT offset;
739 /* The declaration or SSA_NAME pointer of the base that we are checking for
740 type change. */
741 tree object;
742 /* Set to true if dynamic type change has been detected. */
743 bool type_maybe_changed;
746 /* Return true if STMT can modify a virtual method table pointer.
748 This function makes special assumptions about both constructors and
749 destructors which are all the functions that are allowed to alter the VMT
750 pointers. It assumes that destructors begin with assignment into all VMT
751 pointers and that constructors essentially look in the following way:
753 1) The very first thing they do is that they call constructors of ancestor
754 sub-objects that have them.
756 2) Then VMT pointers of this and all its ancestors is set to new values
757 corresponding to the type corresponding to the constructor.
759 3) Only afterwards, other stuff such as constructor of member sub-objects
760 and the code written by the user is run. Only this may include calling
761 virtual functions, directly or indirectly.
763 There is no way to call a constructor of an ancestor sub-object in any
764 other way.
766 This means that we do not have to care whether constructors get the correct
767 type information because they will always change it (in fact, if we define
768 the type to be given by the VMT pointer, it is undefined).
770 The most important fact to derive from the above is that if, for some
771 statement in the section 3, we try to detect whether the dynamic type has
772 changed, we can safely ignore all calls as we examine the function body
773 backwards until we reach statements in section 2 because these calls cannot
774 be ancestor constructors or destructors (if the input is not bogus) and so
775 do not change the dynamic type (this holds true only for automatically
776 allocated objects but at the moment we devirtualize only these). We then
777 must detect that statements in section 2 change the dynamic type and can try
778 to derive the new type. That is enough and we can stop, we will never see
779 the calls into constructors of sub-objects in this code. Therefore we can
780 safely ignore all call statements that we traverse.
783 static bool
784 stmt_may_be_vtbl_ptr_store (gimple *stmt)
786 if (is_gimple_call (stmt))
787 return false;
788 if (gimple_clobber_p (stmt))
789 return false;
790 else if (is_gimple_assign (stmt))
792 tree lhs = gimple_assign_lhs (stmt);
794 if (!AGGREGATE_TYPE_P (TREE_TYPE (lhs)))
796 if (flag_strict_aliasing
797 && !POINTER_TYPE_P (TREE_TYPE (lhs)))
798 return false;
800 if (TREE_CODE (lhs) == COMPONENT_REF
801 && !DECL_VIRTUAL_P (TREE_OPERAND (lhs, 1)))
802 return false;
803 /* In the future we might want to use get_ref_base_and_extent to find
804 if there is a field corresponding to the offset and if so, proceed
805 almost like if it was a component ref. */
808 return true;
811 /* Callback of walk_aliased_vdefs and a helper function for detect_type_change
812 to check whether a particular statement may modify the virtual table
813 pointerIt stores its result into DATA, which points to a
814 prop_type_change_info structure. */
816 static bool
817 check_stmt_for_type_change (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
819 gimple *stmt = SSA_NAME_DEF_STMT (vdef);
820 struct prop_type_change_info *tci = (struct prop_type_change_info *) data;
822 if (stmt_may_be_vtbl_ptr_store (stmt))
824 tci->type_maybe_changed = true;
825 return true;
827 else
828 return false;
831 /* See if ARG is PARAM_DECl describing instance passed by pointer
832 or reference in FUNCTION. Return false if the dynamic type may change
833 in between beggining of the function until CALL is invoked.
835 Generally functions are not allowed to change type of such instances,
836 but they call destructors. We assume that methods cannot destroy the THIS
837 pointer. Also as a special cases, constructor and destructors may change
838 type of the THIS pointer. */
840 static bool
841 param_type_may_change_p (tree function, tree arg, gimple *call)
843 /* Pure functions cannot do any changes on the dynamic type;
844 that require writting to memory. */
845 if (flags_from_decl_or_type (function) & (ECF_PURE | ECF_CONST))
846 return false;
847 /* We need to check if we are within inlined consturctor
848 or destructor (ideally we would have way to check that the
849 inline cdtor is actually working on ARG, but we don't have
850 easy tie on this, so punt on all non-pure cdtors.
851 We may also record the types of cdtors and once we know type
852 of the instance match them.
854 Also code unification optimizations may merge calls from
855 different blocks making return values unreliable. So
856 do nothing during late optimization. */
857 if (DECL_STRUCT_FUNCTION (function)->after_inlining)
858 return true;
859 if (TREE_CODE (arg) == SSA_NAME
860 && SSA_NAME_IS_DEFAULT_DEF (arg)
861 && TREE_CODE (SSA_NAME_VAR (arg)) == PARM_DECL)
863 /* Normal (non-THIS) argument. */
864 if ((SSA_NAME_VAR (arg) != DECL_ARGUMENTS (function)
865 || TREE_CODE (TREE_TYPE (function)) != METHOD_TYPE)
866 /* THIS pointer of an method - here we want to watch constructors
867 and destructors as those definitely may change the dynamic
868 type. */
869 || (TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE
870 && !DECL_CXX_CONSTRUCTOR_P (function)
871 && !DECL_CXX_DESTRUCTOR_P (function)
872 && (SSA_NAME_VAR (arg) == DECL_ARGUMENTS (function))))
874 /* Walk the inline stack and watch out for ctors/dtors. */
875 for (tree block = gimple_block (call); block && TREE_CODE (block) == BLOCK;
876 block = BLOCK_SUPERCONTEXT (block))
877 if (inlined_polymorphic_ctor_dtor_block_p (block, false))
878 return true;
879 return false;
882 return true;
885 /* Detect whether the dynamic type of ARG of COMP_TYPE has changed (before
886 callsite CALL) by looking for assignments to its virtual table pointer. If
887 it is, return true. ARG is the object itself (not a pointer
888 to it, unless dereferenced). BASE is the base of the memory access as
889 returned by get_ref_base_and_extent, as is the offset.
891 This is helper function for detect_type_change and detect_type_change_ssa
892 that does the heavy work which is usually unnecesary. */
894 static bool
895 detect_type_change_from_memory_writes (ipa_func_body_info *fbi, tree arg,
896 tree base, tree comp_type, gcall *call,
897 HOST_WIDE_INT offset)
899 struct prop_type_change_info tci;
900 ao_ref ao;
902 gcc_checking_assert (DECL_P (arg)
903 || TREE_CODE (arg) == MEM_REF
904 || handled_component_p (arg));
906 comp_type = TYPE_MAIN_VARIANT (comp_type);
908 /* Const calls cannot call virtual methods through VMT and so type changes do
909 not matter. */
910 if (!flag_devirtualize || !gimple_vuse (call)
911 /* Be sure expected_type is polymorphic. */
912 || !comp_type
913 || TREE_CODE (comp_type) != RECORD_TYPE
914 || !TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type))
915 || !BINFO_VTABLE (TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type))))
916 return true;
918 if (fbi->aa_walk_budget == 0)
919 return false;
921 ao_ref_init (&ao, arg);
922 ao.base = base;
923 ao.offset = offset;
924 ao.size = POINTER_SIZE;
925 ao.max_size = ao.size;
927 tci.offset = offset;
928 tci.object = get_base_address (arg);
929 tci.type_maybe_changed = false;
931 int walked
932 = walk_aliased_vdefs (&ao, gimple_vuse (call), check_stmt_for_type_change,
933 &tci, NULL, NULL, fbi->aa_walk_budget);
934 if (walked >= 0)
935 fbi->aa_walk_budget -= walked;
936 else
937 fbi->aa_walk_budget = 0;
939 if (walked >= 0 && !tci.type_maybe_changed)
940 return false;
942 return true;
945 /* Detect whether the dynamic type of ARG of COMP_TYPE may have changed.
946 If it is, return true. ARG is the object itself (not a pointer
947 to it, unless dereferenced). BASE is the base of the memory access as
948 returned by get_ref_base_and_extent, as is the offset. */
950 static bool
951 detect_type_change (ipa_func_body_info *fbi, tree arg, tree base,
952 tree comp_type, gcall *call,
953 HOST_WIDE_INT offset)
955 if (!flag_devirtualize)
956 return false;
958 if (TREE_CODE (base) == MEM_REF
959 && !param_type_may_change_p (current_function_decl,
960 TREE_OPERAND (base, 0),
961 call))
962 return false;
963 return detect_type_change_from_memory_writes (fbi, arg, base, comp_type,
964 call, offset);
967 /* Like detect_type_change but ARG is supposed to be a non-dereferenced pointer
968 SSA name (its dereference will become the base and the offset is assumed to
969 be zero). */
971 static bool
972 detect_type_change_ssa (ipa_func_body_info *fbi, tree arg, tree comp_type,
973 gcall *call)
975 gcc_checking_assert (TREE_CODE (arg) == SSA_NAME);
976 if (!flag_devirtualize
977 || !POINTER_TYPE_P (TREE_TYPE (arg)))
978 return false;
980 if (!param_type_may_change_p (current_function_decl, arg, call))
981 return false;
983 arg = build2 (MEM_REF, ptr_type_node, arg,
984 build_int_cst (ptr_type_node, 0));
986 return detect_type_change_from_memory_writes (fbi, arg, arg, comp_type,
987 call, 0);
990 /* Callback of walk_aliased_vdefs. Flags that it has been invoked to the
991 boolean variable pointed to by DATA. */
993 static bool
994 mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
995 void *data)
997 bool *b = (bool *) data;
998 *b = true;
999 return true;
1002 /* Find the nearest valid aa status for parameter specified by INDEX that
1003 dominates BB. */
1005 static struct ipa_param_aa_status *
1006 find_dominating_aa_status (struct ipa_func_body_info *fbi, basic_block bb,
1007 int index)
1009 while (true)
1011 bb = get_immediate_dominator (CDI_DOMINATORS, bb);
1012 if (!bb)
1013 return NULL;
1014 struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
1015 if (!bi->param_aa_statuses.is_empty ()
1016 && bi->param_aa_statuses[index].valid)
1017 return &bi->param_aa_statuses[index];
1021 /* Get AA status structure for the given BB and parameter with INDEX. Allocate
1022 structures and/or intialize the result with a dominating description as
1023 necessary. */
1025 static struct ipa_param_aa_status *
1026 parm_bb_aa_status_for_bb (struct ipa_func_body_info *fbi, basic_block bb,
1027 int index)
1029 gcc_checking_assert (fbi);
1030 struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
1031 if (bi->param_aa_statuses.is_empty ())
1032 bi->param_aa_statuses.safe_grow_cleared (fbi->param_count, true);
1033 struct ipa_param_aa_status *paa = &bi->param_aa_statuses[index];
1034 if (!paa->valid)
1036 gcc_checking_assert (!paa->parm_modified
1037 && !paa->ref_modified
1038 && !paa->pt_modified);
1039 struct ipa_param_aa_status *dom_paa;
1040 dom_paa = find_dominating_aa_status (fbi, bb, index);
1041 if (dom_paa)
1042 *paa = *dom_paa;
1043 else
1044 paa->valid = true;
1047 return paa;
1050 /* Return true if a load from a formal parameter PARM_LOAD is known to retrieve
1051 a value known not to be modified in this function before reaching the
1052 statement STMT. FBI holds information about the function we have so far
1053 gathered but do not survive the summary building stage. */
1055 static bool
1056 parm_preserved_before_stmt_p (struct ipa_func_body_info *fbi, int index,
1057 gimple *stmt, tree parm_load)
1059 struct ipa_param_aa_status *paa;
1060 bool modified = false;
1061 ao_ref refd;
1063 tree base = get_base_address (parm_load);
1064 gcc_assert (TREE_CODE (base) == PARM_DECL);
1065 if (TREE_READONLY (base))
1066 return true;
1068 gcc_checking_assert (fbi);
1069 paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (stmt), index);
1070 if (paa->parm_modified || fbi->aa_walk_budget == 0)
1071 return false;
1073 gcc_checking_assert (gimple_vuse (stmt) != NULL_TREE);
1074 ao_ref_init (&refd, parm_load);
1075 int walked = walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified,
1076 &modified, NULL, NULL,
1077 fbi->aa_walk_budget);
1078 if (walked < 0)
1080 modified = true;
1081 fbi->aa_walk_budget = 0;
1083 else
1084 fbi->aa_walk_budget -= walked;
1085 if (paa && modified)
1086 paa->parm_modified = true;
1087 return !modified;
1090 /* If STMT is an assignment that loads a value from an parameter declaration,
1091 return the index of the parameter in ipa_node_params which has not been
1092 modified. Otherwise return -1. */
1094 static int
1095 load_from_unmodified_param (struct ipa_func_body_info *fbi,
1096 vec<ipa_param_descriptor, va_gc> *descriptors,
1097 gimple *stmt)
1099 int index;
1100 tree op1;
1102 if (!gimple_assign_single_p (stmt))
1103 return -1;
1105 op1 = gimple_assign_rhs1 (stmt);
1106 if (TREE_CODE (op1) != PARM_DECL)
1107 return -1;
1109 index = ipa_get_param_decl_index_1 (descriptors, op1);
1110 if (index < 0
1111 || !parm_preserved_before_stmt_p (fbi, index, stmt, op1))
1112 return -1;
1114 return index;
1117 /* Return true if memory reference REF (which must be a load through parameter
1118 with INDEX) loads data that are known to be unmodified in this function
1119 before reaching statement STMT. */
1121 static bool
1122 parm_ref_data_preserved_p (struct ipa_func_body_info *fbi,
1123 int index, gimple *stmt, tree ref)
1125 struct ipa_param_aa_status *paa;
1126 bool modified = false;
1127 ao_ref refd;
1129 gcc_checking_assert (fbi);
1130 paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (stmt), index);
1131 if (paa->ref_modified || fbi->aa_walk_budget == 0)
1132 return false;
1134 gcc_checking_assert (gimple_vuse (stmt));
1135 ao_ref_init (&refd, ref);
1136 int walked = walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified,
1137 &modified, NULL, NULL,
1138 fbi->aa_walk_budget);
1139 if (walked < 0)
1141 modified = true;
1142 fbi->aa_walk_budget = 0;
1144 else
1145 fbi->aa_walk_budget -= walked;
1146 if (modified)
1147 paa->ref_modified = true;
1148 return !modified;
1151 /* Return true if the data pointed to by PARM (which is a parameter with INDEX)
1152 is known to be unmodified in this function before reaching call statement
1153 CALL into which it is passed. FBI describes the function body. */
1155 static bool
1156 parm_ref_data_pass_through_p (struct ipa_func_body_info *fbi, int index,
1157 gimple *call, tree parm)
1159 bool modified = false;
1160 ao_ref refd;
1162 /* It's unnecessary to calculate anything about memory contnets for a const
1163 function because it is not goin to use it. But do not cache the result
1164 either. Also, no such calculations for non-pointers. */
1165 if (!gimple_vuse (call)
1166 || !POINTER_TYPE_P (TREE_TYPE (parm)))
1167 return false;
1169 struct ipa_param_aa_status *paa = parm_bb_aa_status_for_bb (fbi,
1170 gimple_bb (call),
1171 index);
1172 if (paa->pt_modified || fbi->aa_walk_budget == 0)
1173 return false;
1175 ao_ref_init_from_ptr_and_size (&refd, parm, NULL_TREE);
1176 int walked = walk_aliased_vdefs (&refd, gimple_vuse (call), mark_modified,
1177 &modified, NULL, NULL,
1178 fbi->aa_walk_budget);
1179 if (walked < 0)
1181 fbi->aa_walk_budget = 0;
1182 modified = true;
1184 else
1185 fbi->aa_walk_budget -= walked;
1186 if (modified)
1187 paa->pt_modified = true;
1188 return !modified;
1191 /* Return true if we can prove that OP is a memory reference loading
1192 data from an aggregate passed as a parameter.
1194 The function works in two modes. If GUARANTEED_UNMODIFIED is NULL, it return
1195 false if it cannot prove that the value has not been modified before the
1196 load in STMT. If GUARANTEED_UNMODIFIED is not NULL, it will return true even
1197 if it cannot prove the value has not been modified, in that case it will
1198 store false to *GUARANTEED_UNMODIFIED, otherwise it will store true there.
1200 INFO and PARMS_AINFO describe parameters of the current function (but the
1201 latter can be NULL), STMT is the load statement. If function returns true,
1202 *INDEX_P, *OFFSET_P and *BY_REF is filled with the parameter index, offset
1203 within the aggregate and whether it is a load from a value passed by
1204 reference respectively.
1206 Return false if the offset divided by BITS_PER_UNIT would not fit into an
1207 unsigned int. */
1209 bool
1210 ipa_load_from_parm_agg (struct ipa_func_body_info *fbi,
1211 vec<ipa_param_descriptor, va_gc> *descriptors,
1212 gimple *stmt, tree op, int *index_p,
1213 HOST_WIDE_INT *offset_p, poly_int64 *size_p,
1214 bool *by_ref_p, bool *guaranteed_unmodified)
1216 int index;
1217 HOST_WIDE_INT size;
1218 bool reverse;
1219 tree base = get_ref_base_and_extent_hwi (op, offset_p, &size, &reverse);
1221 if (!base
1222 || (*offset_p / BITS_PER_UNIT) > UINT_MAX)
1223 return false;
1225 /* We can not propagate across volatile loads. */
1226 if (TREE_THIS_VOLATILE (op))
1227 return false;
1229 if (DECL_P (base))
1231 int index = ipa_get_param_decl_index_1 (descriptors, base);
1232 if (index >= 0
1233 && parm_preserved_before_stmt_p (fbi, index, stmt, op))
1235 *index_p = index;
1236 *by_ref_p = false;
1237 if (size_p)
1238 *size_p = size;
1239 if (guaranteed_unmodified)
1240 *guaranteed_unmodified = true;
1241 return true;
1243 return false;
1246 if (TREE_CODE (base) != MEM_REF
1247 || TREE_CODE (TREE_OPERAND (base, 0)) != SSA_NAME
1248 || !integer_zerop (TREE_OPERAND (base, 1)))
1249 return false;
1251 if (SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (base, 0)))
1253 tree parm = SSA_NAME_VAR (TREE_OPERAND (base, 0));
1254 index = ipa_get_param_decl_index_1 (descriptors, parm);
1256 else
1258 /* This branch catches situations where a pointer parameter is not a
1259 gimple register, for example:
1261 void hip7(S*) (struct S * p)
1263 void (*<T2e4>) (struct S *) D.1867;
1264 struct S * p.1;
1266 <bb 2>:
1267 p.1_1 = p;
1268 D.1867_2 = p.1_1->f;
1269 D.1867_2 ();
1270 gdp = &p;
1273 gimple *def = SSA_NAME_DEF_STMT (TREE_OPERAND (base, 0));
1274 index = load_from_unmodified_param (fbi, descriptors, def);
1277 if (index >= 0)
1279 bool data_preserved = parm_ref_data_preserved_p (fbi, index, stmt, op);
1280 if (!data_preserved && !guaranteed_unmodified)
1281 return false;
1283 *index_p = index;
1284 *by_ref_p = true;
1285 if (size_p)
1286 *size_p = size;
1287 if (guaranteed_unmodified)
1288 *guaranteed_unmodified = data_preserved;
1289 return true;
1291 return false;
1294 /* If STMT is an assignment that loads a value from a parameter declaration,
1295 or from an aggregate passed as the parameter either by value or reference,
1296 return the index of the parameter in ipa_node_params. Otherwise return -1.
1298 FBI holds gathered information about the function. INFO describes
1299 parameters of the function, STMT is the assignment statement. If it is a
1300 memory load from an aggregate, *OFFSET_P is filled with offset within the
1301 aggregate, and *BY_REF_P specifies whether the aggregate is passed by
1302 reference. */
1304 static int
1305 load_from_unmodified_param_or_agg (struct ipa_func_body_info *fbi,
1306 class ipa_node_params *info,
1307 gimple *stmt,
1308 HOST_WIDE_INT *offset_p,
1309 bool *by_ref_p)
1311 int index = load_from_unmodified_param (fbi, info->descriptors, stmt);
1312 poly_int64 size;
1314 /* Load value from a parameter declaration. */
1315 if (index >= 0)
1317 *offset_p = -1;
1318 return index;
1321 if (!gimple_assign_load_p (stmt))
1322 return -1;
1324 tree rhs = gimple_assign_rhs1 (stmt);
1326 /* Skip memory reference containing VIEW_CONVERT_EXPR. */
1327 for (tree t = rhs; handled_component_p (t); t = TREE_OPERAND (t, 0))
1328 if (TREE_CODE (t) == VIEW_CONVERT_EXPR)
1329 return -1;
1331 /* Skip memory reference containing bit-field. */
1332 if (TREE_CODE (rhs) == BIT_FIELD_REF
1333 || contains_bitfld_component_ref_p (rhs))
1334 return -1;
1336 if (!ipa_load_from_parm_agg (fbi, info->descriptors, stmt, rhs, &index,
1337 offset_p, &size, by_ref_p))
1338 return -1;
1340 gcc_assert (!maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (rhs))),
1341 size));
1342 if (!*by_ref_p)
1344 tree param_type = ipa_get_type (info, index);
1346 if (!param_type || !AGGREGATE_TYPE_P (param_type))
1347 return -1;
1349 else if (TREE_THIS_VOLATILE (rhs))
1350 return -1;
1352 return index;
1355 /* Walk pointer adjustemnts from OP (such as POINTER_PLUS and ADDR_EXPR)
1356 to find original pointer. Initialize RET to the pointer which results from
1357 the walk.
1358 If offset is known return true and initialize OFFSET_RET. */
1360 bool
1361 unadjusted_ptr_and_unit_offset (tree op, tree *ret, poly_int64 *offset_ret)
1363 poly_int64 offset = 0;
1364 bool offset_known = true;
1365 int i;
1367 for (i = 0; i < param_ipa_jump_function_lookups; i++)
1369 if (TREE_CODE (op) == ADDR_EXPR)
1371 poly_int64 extra_offset = 0;
1372 tree base = get_addr_base_and_unit_offset (TREE_OPERAND (op, 0),
1373 &offset);
1374 if (!base)
1376 base = get_base_address (TREE_OPERAND (op, 0));
1377 if (TREE_CODE (base) != MEM_REF)
1378 break;
1379 offset_known = false;
1381 else
1383 if (TREE_CODE (base) != MEM_REF)
1384 break;
1385 offset += extra_offset;
1387 op = TREE_OPERAND (base, 0);
1388 if (mem_ref_offset (base).to_shwi (&extra_offset))
1389 offset += extra_offset;
1390 else
1391 offset_known = false;
1393 else if (TREE_CODE (op) == SSA_NAME
1394 && !SSA_NAME_IS_DEFAULT_DEF (op))
1396 gimple *pstmt = SSA_NAME_DEF_STMT (op);
1398 if (gimple_assign_single_p (pstmt))
1399 op = gimple_assign_rhs1 (pstmt);
1400 else if (is_gimple_assign (pstmt)
1401 && gimple_assign_rhs_code (pstmt) == POINTER_PLUS_EXPR)
1403 poly_int64 extra_offset = 0;
1404 if (ptrdiff_tree_p (gimple_assign_rhs2 (pstmt),
1405 &extra_offset))
1406 offset += extra_offset;
1407 else
1408 offset_known = false;
1409 op = gimple_assign_rhs1 (pstmt);
1411 else
1412 break;
1414 else
1415 break;
1417 *ret = op;
1418 *offset_ret = offset;
1419 return offset_known;
1422 /* Given that an actual argument is an SSA_NAME (given in NAME) and is a result
1423 of an assignment statement STMT, try to determine whether we are actually
1424 handling any of the following cases and construct an appropriate jump
1425 function into JFUNC if so:
1427 1) The passed value is loaded from a formal parameter which is not a gimple
1428 register (most probably because it is addressable, the value has to be
1429 scalar) and we can guarantee the value has not changed. This case can
1430 therefore be described by a simple pass-through jump function. For example:
1432 foo (int a)
1434 int a.0;
1436 a.0_2 = a;
1437 bar (a.0_2);
1439 2) The passed value can be described by a simple arithmetic pass-through
1440 jump function. E.g.
1442 foo (int a)
1444 int D.2064;
1446 D.2064_4 = a.1(D) + 4;
1447 bar (D.2064_4);
1449 This case can also occur in combination of the previous one, e.g.:
1451 foo (int a, int z)
1453 int a.0;
1454 int D.2064;
1456 a.0_3 = a;
1457 D.2064_4 = a.0_3 + 4;
1458 foo (D.2064_4);
1460 3) The passed value is an address of an object within another one (which
1461 also passed by reference). Such situations are described by an ancestor
1462 jump function and describe situations such as:
1464 B::foo() (struct B * const this)
1466 struct A * D.1845;
1468 D.1845_2 = &this_1(D)->D.1748;
1469 A::bar (D.1845_2);
1471 INFO is the structure describing individual parameters access different
1472 stages of IPA optimizations. PARMS_AINFO contains the information that is
1473 only needed for intraprocedural analysis. */
1475 static void
1476 compute_complex_assign_jump_func (struct ipa_func_body_info *fbi,
1477 class ipa_node_params *info,
1478 struct ipa_jump_func *jfunc,
1479 gcall *call, gimple *stmt, tree name,
1480 tree param_type)
1482 HOST_WIDE_INT offset, size;
1483 tree op1, tc_ssa, base, ssa;
1484 bool reverse;
1485 int index;
1487 op1 = gimple_assign_rhs1 (stmt);
1489 if (TREE_CODE (op1) == SSA_NAME)
1491 if (SSA_NAME_IS_DEFAULT_DEF (op1))
1492 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (op1));
1493 else
1494 index = load_from_unmodified_param (fbi, info->descriptors,
1495 SSA_NAME_DEF_STMT (op1));
1496 tc_ssa = op1;
1498 else
1500 index = load_from_unmodified_param (fbi, info->descriptors, stmt);
1501 tc_ssa = gimple_assign_lhs (stmt);
1504 if (index >= 0)
1506 switch (gimple_assign_rhs_class (stmt))
1508 case GIMPLE_BINARY_RHS:
1510 tree op2 = gimple_assign_rhs2 (stmt);
1511 if (!is_gimple_ip_invariant (op2)
1512 || ((TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))
1513 != tcc_comparison)
1514 && !useless_type_conversion_p (TREE_TYPE (name),
1515 TREE_TYPE (op1))))
1516 return;
1518 ipa_set_jf_arith_pass_through (jfunc, index, op2,
1519 gimple_assign_rhs_code (stmt));
1520 break;
1522 case GIMPLE_SINGLE_RHS:
1524 bool agg_p = parm_ref_data_pass_through_p (fbi, index, call,
1525 tc_ssa);
1526 ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
1527 break;
1529 case GIMPLE_UNARY_RHS:
1530 if (!CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt)))
1531 ipa_set_jf_unary_pass_through (jfunc, index,
1532 gimple_assign_rhs_code (stmt));
1533 default:;
1535 return;
1538 if (TREE_CODE (op1) != ADDR_EXPR)
1539 return;
1540 op1 = TREE_OPERAND (op1, 0);
1541 base = get_ref_base_and_extent_hwi (op1, &offset, &size, &reverse);
1542 offset_int mem_offset;
1543 if (!base
1544 || TREE_CODE (base) != MEM_REF
1545 || !mem_ref_offset (base).is_constant (&mem_offset))
1546 return;
1547 offset += mem_offset.to_short_addr () * BITS_PER_UNIT;
1548 ssa = TREE_OPERAND (base, 0);
1549 if (TREE_CODE (ssa) != SSA_NAME
1550 || !SSA_NAME_IS_DEFAULT_DEF (ssa)
1551 || offset < 0)
1552 return;
1554 /* Dynamic types are changed in constructors and destructors. */
1555 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (ssa));
1556 if (index >= 0 && param_type && POINTER_TYPE_P (param_type))
1557 ipa_set_ancestor_jf (jfunc, offset, index,
1558 parm_ref_data_pass_through_p (fbi, index, call, ssa),
1559 false);
1562 /* Extract the base, offset and MEM_REF expression from a statement ASSIGN if
1563 it looks like:
1565 iftmp.1_3 = &obj_2(D)->D.1762;
1567 The base of the MEM_REF must be a default definition SSA NAME of a
1568 parameter. Return NULL_TREE if it looks otherwise. If case of success, the
1569 whole MEM_REF expression is returned and the offset calculated from any
1570 handled components and the MEM_REF itself is stored into *OFFSET. The whole
1571 RHS stripped off the ADDR_EXPR is stored into *OBJ_P. */
1573 static tree
1574 get_ancestor_addr_info (gimple *assign, tree *obj_p, HOST_WIDE_INT *offset)
1576 HOST_WIDE_INT size;
1577 tree expr, parm, obj;
1578 bool reverse;
1580 if (!gimple_assign_single_p (assign))
1581 return NULL_TREE;
1582 expr = gimple_assign_rhs1 (assign);
1584 if (TREE_CODE (expr) != ADDR_EXPR)
1585 return NULL_TREE;
1586 expr = TREE_OPERAND (expr, 0);
1587 obj = expr;
1588 expr = get_ref_base_and_extent_hwi (expr, offset, &size, &reverse);
1590 offset_int mem_offset;
1591 if (!expr
1592 || TREE_CODE (expr) != MEM_REF
1593 || !mem_ref_offset (expr).is_constant (&mem_offset))
1594 return NULL_TREE;
1595 parm = TREE_OPERAND (expr, 0);
1596 if (TREE_CODE (parm) != SSA_NAME
1597 || !SSA_NAME_IS_DEFAULT_DEF (parm)
1598 || TREE_CODE (SSA_NAME_VAR (parm)) != PARM_DECL)
1599 return NULL_TREE;
1601 *offset += mem_offset.to_short_addr () * BITS_PER_UNIT;
1602 *obj_p = obj;
1603 return expr;
1607 /* Given that an actual argument is an SSA_NAME that is a result of a phi
1608 statement PHI, try to find out whether NAME is in fact a
1609 multiple-inheritance typecast from a descendant into an ancestor of a formal
1610 parameter and thus can be described by an ancestor jump function and if so,
1611 write the appropriate function into JFUNC.
1613 Essentially we want to match the following pattern:
1615 if (obj_2(D) != 0B)
1616 goto <bb 3>;
1617 else
1618 goto <bb 4>;
1620 <bb 3>:
1621 iftmp.1_3 = &obj_2(D)->D.1762;
1623 <bb 4>:
1624 # iftmp.1_1 = PHI <iftmp.1_3(3), 0B(2)>
1625 D.1879_6 = middleman_1 (iftmp.1_1, i_5(D));
1626 return D.1879_6; */
1628 static void
1629 compute_complex_ancestor_jump_func (struct ipa_func_body_info *fbi,
1630 class ipa_node_params *info,
1631 struct ipa_jump_func *jfunc,
1632 gcall *call, gphi *phi)
1634 HOST_WIDE_INT offset;
1635 gimple *assign;
1636 basic_block phi_bb, assign_bb, cond_bb;
1637 tree tmp, parm, expr, obj;
1638 int index, i;
1640 if (gimple_phi_num_args (phi) != 2)
1641 return;
1643 if (integer_zerop (PHI_ARG_DEF (phi, 1)))
1644 tmp = PHI_ARG_DEF (phi, 0);
1645 else if (integer_zerop (PHI_ARG_DEF (phi, 0)))
1646 tmp = PHI_ARG_DEF (phi, 1);
1647 else
1648 return;
1649 if (TREE_CODE (tmp) != SSA_NAME
1650 || SSA_NAME_IS_DEFAULT_DEF (tmp)
1651 || !POINTER_TYPE_P (TREE_TYPE (tmp))
1652 || TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) != RECORD_TYPE)
1653 return;
1655 assign = SSA_NAME_DEF_STMT (tmp);
1656 assign_bb = gimple_bb (assign);
1657 if (!single_pred_p (assign_bb))
1658 return;
1659 expr = get_ancestor_addr_info (assign, &obj, &offset);
1660 if (!expr)
1661 return;
1662 parm = TREE_OPERAND (expr, 0);
1663 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (parm));
1664 if (index < 0)
1665 return;
1667 cond_bb = single_pred (assign_bb);
1668 gcond *cond = safe_dyn_cast <gcond *> (*gsi_last_bb (cond_bb));
1669 if (!cond
1670 || gimple_cond_code (cond) != NE_EXPR
1671 || gimple_cond_lhs (cond) != parm
1672 || !integer_zerop (gimple_cond_rhs (cond)))
1673 return;
1675 phi_bb = gimple_bb (phi);
1676 for (i = 0; i < 2; i++)
1678 basic_block pred = EDGE_PRED (phi_bb, i)->src;
1679 if (pred != assign_bb && pred != cond_bb)
1680 return;
1683 ipa_set_ancestor_jf (jfunc, offset, index,
1684 parm_ref_data_pass_through_p (fbi, index, call, parm),
1685 true);
1688 /* Inspect the given TYPE and return true iff it has the same structure (the
1689 same number of fields of the same types) as a C++ member pointer. If
1690 METHOD_PTR and DELTA are non-NULL, store the trees representing the
1691 corresponding fields there. */
1693 static bool
1694 type_like_member_ptr_p (tree type, tree *method_ptr, tree *delta)
1696 tree fld;
1698 if (TREE_CODE (type) != RECORD_TYPE)
1699 return false;
1701 fld = TYPE_FIELDS (type);
1702 if (!fld || !POINTER_TYPE_P (TREE_TYPE (fld))
1703 || TREE_CODE (TREE_TYPE (TREE_TYPE (fld))) != METHOD_TYPE
1704 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
1705 return false;
1707 if (method_ptr)
1708 *method_ptr = fld;
1710 fld = DECL_CHAIN (fld);
1711 if (!fld || INTEGRAL_TYPE_P (fld)
1712 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
1713 return false;
1714 if (delta)
1715 *delta = fld;
1717 if (DECL_CHAIN (fld))
1718 return false;
1720 return true;
1723 /* If RHS is an SSA_NAME and it is defined by a simple copy assign statement,
1724 return the rhs of its defining statement, and this statement is stored in
1725 *RHS_STMT. Otherwise return RHS as it is. */
1727 static inline tree
1728 get_ssa_def_if_simple_copy (tree rhs, gimple **rhs_stmt)
1730 while (TREE_CODE (rhs) == SSA_NAME && !SSA_NAME_IS_DEFAULT_DEF (rhs))
1732 gimple *def_stmt = SSA_NAME_DEF_STMT (rhs);
1734 if (gimple_assign_single_p (def_stmt))
1735 rhs = gimple_assign_rhs1 (def_stmt);
1736 else
1737 break;
1738 *rhs_stmt = def_stmt;
1740 return rhs;
1743 /* Simple linked list, describing contents of an aggregate before call. */
1745 struct ipa_known_agg_contents_list
1747 /* Offset and size of the described part of the aggregate. */
1748 HOST_WIDE_INT offset, size;
1750 /* Type of the described part of the aggregate. */
1751 tree type;
1753 /* Known constant value or jump function data describing contents. */
1754 struct ipa_load_agg_data value;
1756 /* Pointer to the next structure in the list. */
1757 struct ipa_known_agg_contents_list *next;
1760 /* Add an aggregate content item into a linked list of
1761 ipa_known_agg_contents_list structure, in which all elements
1762 are sorted ascendingly by offset. */
1764 static inline void
1765 add_to_agg_contents_list (struct ipa_known_agg_contents_list **plist,
1766 struct ipa_known_agg_contents_list *item)
1768 struct ipa_known_agg_contents_list *list = *plist;
1770 for (; list; list = list->next)
1772 if (list->offset >= item->offset)
1773 break;
1775 plist = &list->next;
1778 item->next = list;
1779 *plist = item;
1782 /* Check whether a given aggregate content is clobbered by certain element in
1783 a linked list of ipa_known_agg_contents_list. */
1785 static inline bool
1786 clobber_by_agg_contents_list_p (struct ipa_known_agg_contents_list *list,
1787 struct ipa_known_agg_contents_list *item)
1789 for (; list; list = list->next)
1791 if (list->offset >= item->offset)
1792 return list->offset < item->offset + item->size;
1794 if (list->offset + list->size > item->offset)
1795 return true;
1798 return false;
1801 /* Build aggregate jump function from LIST, assuming there are exactly
1802 VALUE_COUNT entries there and that offset of the passed argument
1803 is ARG_OFFSET and store it into JFUNC. */
1805 static void
1806 build_agg_jump_func_from_list (struct ipa_known_agg_contents_list *list,
1807 int value_count, HOST_WIDE_INT arg_offset,
1808 struct ipa_jump_func *jfunc)
1810 vec_safe_reserve (jfunc->agg.items, value_count, true);
1811 for (; list; list = list->next)
1813 struct ipa_agg_jf_item item;
1814 tree operand = list->value.pass_through.operand;
1816 if (list->value.pass_through.formal_id >= 0)
1818 /* Content value is derived from some formal paramerter. */
1819 if (list->value.offset >= 0)
1820 item.jftype = IPA_JF_LOAD_AGG;
1821 else
1822 item.jftype = IPA_JF_PASS_THROUGH;
1824 item.value.load_agg = list->value;
1825 if (operand)
1826 item.value.pass_through.operand
1827 = unshare_expr_without_location (operand);
1829 else if (operand)
1831 /* Content value is known constant. */
1832 item.jftype = IPA_JF_CONST;
1833 item.value.constant = unshare_expr_without_location (operand);
1835 else
1836 continue;
1838 item.type = list->type;
1839 gcc_assert (tree_to_shwi (TYPE_SIZE (list->type)) == list->size);
1841 item.offset = list->offset - arg_offset;
1842 gcc_assert ((item.offset % BITS_PER_UNIT) == 0);
1844 jfunc->agg.items->quick_push (item);
1848 /* Given an assignment statement STMT, try to collect information into
1849 AGG_VALUE that will be used to construct jump function for RHS of the
1850 assignment, from which content value of an aggregate part comes.
1852 Besides constant and simple pass-through jump functions, also try to
1853 identify whether it matches the following pattern that can be described by
1854 a load-value-from-aggregate jump function, which is a derivative of simple
1855 pass-through jump function.
1857 foo (int *p)
1861 *(q_5 + 4) = *(p_3(D) + 28) op 1;
1862 bar (q_5);
1865 Here IPA_LOAD_AGG_DATA data structure is informative enough to describe
1866 constant, simple pass-through and load-vale-from-aggregate. If value
1867 is constant, it will be kept in field OPERAND, and field FORMAL_ID is
1868 set to -1. For simple pass-through and load-value-from-aggregate, field
1869 FORMAL_ID specifies the related formal parameter index, and field
1870 OFFSET can be used to distinguish them, -1 means simple pass-through,
1871 otherwise means load-value-from-aggregate. */
1873 static void
1874 analyze_agg_content_value (struct ipa_func_body_info *fbi,
1875 struct ipa_load_agg_data *agg_value,
1876 gimple *stmt)
1878 tree lhs = gimple_assign_lhs (stmt);
1879 tree rhs1 = gimple_assign_rhs1 (stmt);
1880 enum tree_code code;
1881 int index = -1;
1883 /* Initialize jump function data for the aggregate part. */
1884 memset (agg_value, 0, sizeof (*agg_value));
1885 agg_value->pass_through.operation = NOP_EXPR;
1886 agg_value->pass_through.formal_id = -1;
1887 agg_value->offset = -1;
1889 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs)) /* TODO: Support aggregate type. */
1890 || TREE_THIS_VOLATILE (lhs)
1891 || TREE_CODE (lhs) == BIT_FIELD_REF
1892 || contains_bitfld_component_ref_p (lhs))
1893 return;
1895 /* Skip SSA copies. */
1896 while (gimple_assign_rhs_class (stmt) == GIMPLE_SINGLE_RHS)
1898 if (TREE_CODE (rhs1) != SSA_NAME || SSA_NAME_IS_DEFAULT_DEF (rhs1))
1899 break;
1901 stmt = SSA_NAME_DEF_STMT (rhs1);
1902 if (!is_gimple_assign (stmt))
1903 break;
1905 rhs1 = gimple_assign_rhs1 (stmt);
1908 if (gphi *phi = dyn_cast<gphi *> (stmt))
1910 /* Also special case like the following (a is a formal parameter):
1912 _12 = *a_11(D).dim[0].stride;
1914 # iftmp.22_9 = PHI <_12(2), 1(3)>
1916 parm.6.dim[0].stride = iftmp.22_9;
1918 __x_MOD_foo (&parm.6, b_31(D));
1920 The aggregate function describing parm.6.dim[0].stride is encoded as a
1921 PASS-THROUGH jump function with ASSERT_EXPR operation whith operand 1
1922 (the constant from the PHI node). */
1924 if (gimple_phi_num_args (phi) != 2)
1925 return;
1926 tree arg0 = gimple_phi_arg_def (phi, 0);
1927 tree arg1 = gimple_phi_arg_def (phi, 1);
1928 tree operand;
1930 if (is_gimple_ip_invariant (arg1))
1932 operand = arg1;
1933 rhs1 = arg0;
1935 else if (is_gimple_ip_invariant (arg0))
1937 operand = arg0;
1938 rhs1 = arg1;
1940 else
1941 return;
1943 rhs1 = get_ssa_def_if_simple_copy (rhs1, &stmt);
1944 if (!is_gimple_assign (stmt))
1945 return;
1947 code = ASSERT_EXPR;
1948 agg_value->pass_through.operand = operand;
1950 else if (is_gimple_assign (stmt))
1952 code = gimple_assign_rhs_code (stmt);
1953 switch (gimple_assign_rhs_class (stmt))
1955 case GIMPLE_SINGLE_RHS:
1956 if (is_gimple_ip_invariant (rhs1))
1958 agg_value->pass_through.operand = rhs1;
1959 return;
1961 code = NOP_EXPR;
1962 break;
1964 case GIMPLE_UNARY_RHS:
1965 /* NOTE: A GIMPLE_UNARY_RHS operation might not be tcc_unary
1966 (truth_not_expr is example), GIMPLE_BINARY_RHS does not imply
1967 tcc_binary, this subtleness is somewhat misleading.
1969 Since tcc_unary is widely used in IPA-CP code to check an operation
1970 with one operand, here we only allow tc_unary operation to avoid
1971 possible problem. Then we can use (opclass == tc_unary) or not to
1972 distinguish unary and binary. */
1973 if (TREE_CODE_CLASS (code) != tcc_unary || CONVERT_EXPR_CODE_P (code))
1974 return;
1976 rhs1 = get_ssa_def_if_simple_copy (rhs1, &stmt);
1977 break;
1979 case GIMPLE_BINARY_RHS:
1981 gimple *rhs1_stmt = stmt;
1982 gimple *rhs2_stmt = stmt;
1983 tree rhs2 = gimple_assign_rhs2 (stmt);
1985 rhs1 = get_ssa_def_if_simple_copy (rhs1, &rhs1_stmt);
1986 rhs2 = get_ssa_def_if_simple_copy (rhs2, &rhs2_stmt);
1988 if (is_gimple_ip_invariant (rhs2))
1990 agg_value->pass_through.operand = rhs2;
1991 stmt = rhs1_stmt;
1993 else if (is_gimple_ip_invariant (rhs1))
1995 if (TREE_CODE_CLASS (code) == tcc_comparison)
1996 code = swap_tree_comparison (code);
1997 else if (!commutative_tree_code (code))
1998 return;
2000 agg_value->pass_through.operand = rhs1;
2001 stmt = rhs2_stmt;
2002 rhs1 = rhs2;
2004 else
2005 return;
2007 if (TREE_CODE_CLASS (code) != tcc_comparison
2008 && !useless_type_conversion_p (TREE_TYPE (lhs),
2009 TREE_TYPE (rhs1)))
2010 return;
2012 break;
2014 default:
2015 return;
2018 else
2019 return;
2021 if (TREE_CODE (rhs1) != SSA_NAME)
2022 index = load_from_unmodified_param_or_agg (fbi, fbi->info, stmt,
2023 &agg_value->offset,
2024 &agg_value->by_ref);
2025 else if (SSA_NAME_IS_DEFAULT_DEF (rhs1))
2026 index = ipa_get_param_decl_index (fbi->info, SSA_NAME_VAR (rhs1));
2028 if (index >= 0)
2030 if (agg_value->offset >= 0)
2031 agg_value->type = TREE_TYPE (rhs1);
2032 agg_value->pass_through.formal_id = index;
2033 agg_value->pass_through.operation = code;
2035 else
2036 agg_value->pass_through.operand = NULL_TREE;
2039 /* If STMT is a memory store to the object whose address is BASE, extract
2040 information (offset, size, and value) into CONTENT, and return true,
2041 otherwise we conservatively assume the whole object is modified with
2042 unknown content, and return false. CHECK_REF means that access to object
2043 is expected to be in form of MEM_REF expression. */
2045 static bool
2046 extract_mem_content (struct ipa_func_body_info *fbi,
2047 gimple *stmt, tree base, bool check_ref,
2048 struct ipa_known_agg_contents_list *content)
2050 HOST_WIDE_INT lhs_offset, lhs_size;
2051 bool reverse;
2053 if (!is_gimple_assign (stmt))
2054 return false;
2056 tree lhs = gimple_assign_lhs (stmt);
2057 tree lhs_base = get_ref_base_and_extent_hwi (lhs, &lhs_offset, &lhs_size,
2058 &reverse);
2059 if (!lhs_base)
2060 return false;
2062 if (check_ref)
2064 if (TREE_CODE (lhs_base) != MEM_REF
2065 || TREE_OPERAND (lhs_base, 0) != base
2066 || !integer_zerop (TREE_OPERAND (lhs_base, 1)))
2067 return false;
2069 else if (lhs_base != base)
2070 return false;
2072 content->offset = lhs_offset;
2073 content->size = lhs_size;
2074 content->type = TREE_TYPE (lhs);
2075 content->next = NULL;
2077 analyze_agg_content_value (fbi, &content->value, stmt);
2078 return true;
2081 /* Traverse statements from CALL backwards, scanning whether an aggregate given
2082 in ARG is filled in constants or values that are derived from caller's
2083 formal parameter in the way described by some kinds of jump functions. FBI
2084 is the context of the caller function for interprocedural analysis. ARG can
2085 either be an aggregate expression or a pointer to an aggregate. ARG_TYPE is
2086 the type of the aggregate, JFUNC is the jump function for the aggregate. */
2088 static void
2089 determine_known_aggregate_parts (struct ipa_func_body_info *fbi,
2090 gcall *call, tree arg,
2091 tree arg_type,
2092 struct ipa_jump_func *jfunc)
2094 struct ipa_known_agg_contents_list *list = NULL, *all_list = NULL;
2095 bitmap visited = NULL;
2096 int item_count = 0, value_count = 0;
2097 HOST_WIDE_INT arg_offset, arg_size;
2098 tree arg_base;
2099 bool check_ref, by_ref;
2100 ao_ref r;
2101 int max_agg_items = opt_for_fn (fbi->node->decl, param_ipa_max_agg_items);
2103 if (max_agg_items == 0)
2104 return;
2106 /* The function operates in three stages. First, we prepare check_ref, r,
2107 arg_base and arg_offset based on what is actually passed as an actual
2108 argument. */
2110 if (POINTER_TYPE_P (arg_type))
2112 by_ref = true;
2113 if (TREE_CODE (arg) == SSA_NAME)
2115 tree type_size;
2116 if (!tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (arg_type)))
2117 || !POINTER_TYPE_P (TREE_TYPE (arg)))
2118 return;
2119 check_ref = true;
2120 arg_base = arg;
2121 arg_offset = 0;
2122 type_size = TYPE_SIZE (TREE_TYPE (arg_type));
2123 arg_size = tree_to_uhwi (type_size);
2124 ao_ref_init_from_ptr_and_size (&r, arg_base, NULL_TREE);
2126 else if (TREE_CODE (arg) == ADDR_EXPR)
2128 bool reverse;
2130 arg = TREE_OPERAND (arg, 0);
2131 arg_base = get_ref_base_and_extent_hwi (arg, &arg_offset,
2132 &arg_size, &reverse);
2133 if (!arg_base)
2134 return;
2135 if (DECL_P (arg_base))
2137 check_ref = false;
2138 ao_ref_init (&r, arg_base);
2140 else
2141 return;
2143 else
2144 return;
2146 else
2148 bool reverse;
2150 gcc_checking_assert (AGGREGATE_TYPE_P (TREE_TYPE (arg)));
2152 by_ref = false;
2153 check_ref = false;
2154 arg_base = get_ref_base_and_extent_hwi (arg, &arg_offset,
2155 &arg_size, &reverse);
2156 if (!arg_base)
2157 return;
2159 ao_ref_init (&r, arg);
2162 /* Second stage traverses virtual SSA web backwards starting from the call
2163 statement, only looks at individual dominating virtual operand (its
2164 definition dominates the call), as long as it is confident that content
2165 of the aggregate is affected by definition of the virtual operand, it
2166 builds a sorted linked list of ipa_agg_jf_list describing that. */
2168 for (tree dom_vuse = gimple_vuse (call);
2169 dom_vuse && fbi->aa_walk_budget > 0;)
2171 gimple *stmt = SSA_NAME_DEF_STMT (dom_vuse);
2173 if (gimple_code (stmt) == GIMPLE_PHI)
2175 dom_vuse = get_continuation_for_phi (stmt, &r, true,
2176 fbi->aa_walk_budget,
2177 &visited, false, NULL, NULL);
2178 continue;
2181 fbi->aa_walk_budget--;
2182 if (stmt_may_clobber_ref_p_1 (stmt, &r))
2184 struct ipa_known_agg_contents_list *content
2185 = XALLOCA (struct ipa_known_agg_contents_list);
2187 if (!extract_mem_content (fbi, stmt, arg_base, check_ref, content))
2188 break;
2190 /* Now we get a dominating virtual operand, and need to check
2191 whether its value is clobbered any other dominating one. */
2192 if ((content->value.pass_through.formal_id >= 0
2193 || content->value.pass_through.operand)
2194 && !clobber_by_agg_contents_list_p (all_list, content)
2195 /* Since IPA-CP stores results with unsigned int offsets, we can
2196 discard those which would not fit now before we stream them to
2197 WPA. */
2198 && (content->offset + content->size - arg_offset
2199 <= (HOST_WIDE_INT) UINT_MAX * BITS_PER_UNIT))
2201 struct ipa_known_agg_contents_list *copy
2202 = XALLOCA (struct ipa_known_agg_contents_list);
2204 /* Add to the list consisting of only dominating virtual
2205 operands, whose definitions can finally reach the call. */
2206 add_to_agg_contents_list (&list, (*copy = *content, copy));
2208 if (++value_count == max_agg_items)
2209 break;
2212 /* Add to the list consisting of all dominating virtual operands. */
2213 add_to_agg_contents_list (&all_list, content);
2215 if (++item_count == 2 * max_agg_items)
2216 break;
2218 dom_vuse = gimple_vuse (stmt);
2221 if (visited)
2222 BITMAP_FREE (visited);
2224 /* Third stage just goes over the list and creates an appropriate vector of
2225 ipa_agg_jf_item structures out of it, of course only if there are
2226 any meaningful items to begin with. */
2228 if (value_count)
2230 jfunc->agg.by_ref = by_ref;
2231 build_agg_jump_func_from_list (list, value_count, arg_offset, jfunc);
2236 /* Return the Ith param type of callee associated with call graph
2237 edge E. */
2239 tree
2240 ipa_get_callee_param_type (struct cgraph_edge *e, int i)
2242 int n;
2243 tree type = (e->callee
2244 ? TREE_TYPE (e->callee->decl)
2245 : gimple_call_fntype (e->call_stmt));
2246 tree t = TYPE_ARG_TYPES (type);
2248 for (n = 0; n < i; n++)
2250 if (!t)
2251 break;
2252 t = TREE_CHAIN (t);
2254 if (t && t != void_list_node)
2255 return TREE_VALUE (t);
2256 if (!e->callee)
2257 return NULL;
2258 t = DECL_ARGUMENTS (e->callee->decl);
2259 for (n = 0; n < i; n++)
2261 if (!t)
2262 return NULL;
2263 t = TREE_CHAIN (t);
2265 if (t)
2266 return TREE_TYPE (t);
2267 return NULL;
2270 /* Return ipa_bits with VALUE and MASK values, which can be either a newly
2271 allocated structure or a previously existing one shared with other jump
2272 functions and/or transformation summaries. */
2274 ipa_bits *
2275 ipa_get_ipa_bits_for_value (const widest_int &value, const widest_int &mask)
2277 ipa_bits tmp;
2278 tmp.value = value;
2279 tmp.mask = mask;
2281 ipa_bits **slot = ipa_bits_hash_table->find_slot (&tmp, INSERT);
2282 if (*slot)
2283 return *slot;
2285 ipa_bits *res = ggc_alloc<ipa_bits> ();
2286 res->value = value;
2287 res->mask = mask;
2288 *slot = res;
2290 return res;
2293 /* Assign to JF a pointer to ipa_bits structure with VALUE and MASK. Use hash
2294 table in order to avoid creating multiple same ipa_bits structures. */
2296 static void
2297 ipa_set_jfunc_bits (ipa_jump_func *jf, const widest_int &value,
2298 const widest_int &mask)
2300 jf->bits = ipa_get_ipa_bits_for_value (value, mask);
2303 /* Return a pointer to an ipa_vr just like TMP, but either find it in
2304 ipa_vr_hash_table or allocate it in GC memory. */
2306 static ipa_vr *
2307 ipa_get_value_range (const vrange &tmp)
2309 inchash::hash hstate;
2310 inchash::add_vrange (tmp, hstate);
2311 hashval_t hash = hstate.end ();
2312 ipa_vr **slot = ipa_vr_hash_table->find_slot_with_hash (&tmp, hash, INSERT);
2313 if (*slot)
2314 return *slot;
2316 ipa_vr *vr = new (ggc_alloc<ipa_vr> ()) ipa_vr (tmp);
2317 *slot = vr;
2318 return vr;
2321 /* Assign to JF a pointer to a range just like TMP but either fetch a
2322 copy from ipa_vr_hash_table or allocate a new on in GC memory. */
2324 static void
2325 ipa_set_jfunc_vr (ipa_jump_func *jf, const vrange &tmp)
2327 jf->m_vr = ipa_get_value_range (tmp);
2330 static void
2331 ipa_set_jfunc_vr (ipa_jump_func *jf, const ipa_vr &vr)
2333 Value_Range tmp;
2334 vr.get_vrange (tmp);
2335 ipa_set_jfunc_vr (jf, tmp);
2338 /* Compute jump function for all arguments of callsite CS and insert the
2339 information in the jump_functions array in the ipa_edge_args corresponding
2340 to this callsite. */
2342 static void
2343 ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
2344 struct cgraph_edge *cs)
2346 ipa_node_params *info = ipa_node_params_sum->get (cs->caller);
2347 ipa_edge_args *args = ipa_edge_args_sum->get_create (cs);
2348 gcall *call = cs->call_stmt;
2349 int n, arg_num = gimple_call_num_args (call);
2350 bool useful_context = false;
2352 if (arg_num == 0 || args->jump_functions)
2353 return;
2354 vec_safe_grow_cleared (args->jump_functions, arg_num, true);
2355 if (flag_devirtualize)
2356 vec_safe_grow_cleared (args->polymorphic_call_contexts, arg_num, true);
2358 if (gimple_call_internal_p (call))
2359 return;
2360 if (ipa_func_spec_opts_forbid_analysis_p (cs->caller))
2361 return;
2363 for (n = 0; n < arg_num; n++)
2365 struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, n);
2366 tree arg = gimple_call_arg (call, n);
2367 tree param_type = ipa_get_callee_param_type (cs, n);
2368 if (flag_devirtualize && POINTER_TYPE_P (TREE_TYPE (arg)))
2370 tree instance;
2371 class ipa_polymorphic_call_context context (cs->caller->decl,
2372 arg, cs->call_stmt,
2373 &instance);
2374 context.get_dynamic_type (instance, arg, NULL, cs->call_stmt,
2375 &fbi->aa_walk_budget);
2376 *ipa_get_ith_polymorhic_call_context (args, n) = context;
2377 if (!context.useless_p ())
2378 useful_context = true;
2381 Value_Range vr (TREE_TYPE (arg));
2382 if (POINTER_TYPE_P (TREE_TYPE (arg)))
2384 bool addr_nonzero = false;
2385 bool strict_overflow = false;
2387 if (TREE_CODE (arg) == SSA_NAME
2388 && param_type
2389 && get_range_query (cfun)->range_of_expr (vr, arg, cs->call_stmt)
2390 && vr.nonzero_p ())
2391 addr_nonzero = true;
2392 else if (tree_single_nonzero_warnv_p (arg, &strict_overflow))
2393 addr_nonzero = true;
2395 if (addr_nonzero)
2397 vr.set_nonzero (TREE_TYPE (arg));
2398 ipa_set_jfunc_vr (jfunc, vr);
2400 else
2401 gcc_assert (!jfunc->m_vr);
2403 else
2405 if (TREE_CODE (arg) == SSA_NAME
2406 && param_type
2407 && Value_Range::supports_type_p (TREE_TYPE (arg))
2408 && Value_Range::supports_type_p (param_type)
2409 && irange::supports_p (TREE_TYPE (arg))
2410 && irange::supports_p (param_type)
2411 && get_range_query (cfun)->range_of_expr (vr, arg, cs->call_stmt)
2412 && !vr.undefined_p ())
2414 Value_Range resvr (vr);
2415 range_cast (resvr, param_type);
2416 if (!resvr.undefined_p () && !resvr.varying_p ())
2417 ipa_set_jfunc_vr (jfunc, resvr);
2418 else
2419 gcc_assert (!jfunc->m_vr);
2421 else
2422 gcc_assert (!jfunc->m_vr);
2425 if (INTEGRAL_TYPE_P (TREE_TYPE (arg))
2426 && (TREE_CODE (arg) == SSA_NAME || TREE_CODE (arg) == INTEGER_CST))
2428 if (TREE_CODE (arg) == SSA_NAME)
2429 ipa_set_jfunc_bits (jfunc, 0,
2430 widest_int::from (get_nonzero_bits (arg),
2431 TYPE_SIGN (TREE_TYPE (arg))));
2432 else
2433 ipa_set_jfunc_bits (jfunc, wi::to_widest (arg), 0);
2435 else if (POINTER_TYPE_P (TREE_TYPE (arg)))
2437 unsigned HOST_WIDE_INT bitpos;
2438 unsigned align;
2440 get_pointer_alignment_1 (arg, &align, &bitpos);
2441 widest_int mask = wi::bit_and_not
2442 (wi::mask<widest_int> (TYPE_PRECISION (TREE_TYPE (arg)), false),
2443 align / BITS_PER_UNIT - 1);
2444 widest_int value = bitpos / BITS_PER_UNIT;
2445 ipa_set_jfunc_bits (jfunc, value, mask);
2447 else
2448 gcc_assert (!jfunc->bits);
2450 if (is_gimple_ip_invariant (arg)
2451 || (VAR_P (arg)
2452 && is_global_var (arg)
2453 && TREE_READONLY (arg)))
2454 ipa_set_jf_constant (jfunc, arg, cs);
2455 else if (!is_gimple_reg_type (TREE_TYPE (arg))
2456 && TREE_CODE (arg) == PARM_DECL)
2458 int index = ipa_get_param_decl_index (info, arg);
2460 gcc_assert (index >=0);
2461 /* Aggregate passed by value, check for pass-through, otherwise we
2462 will attempt to fill in aggregate contents later in this
2463 for cycle. */
2464 if (parm_preserved_before_stmt_p (fbi, index, call, arg))
2466 ipa_set_jf_simple_pass_through (jfunc, index, false);
2467 continue;
2470 else if (TREE_CODE (arg) == SSA_NAME)
2472 if (SSA_NAME_IS_DEFAULT_DEF (arg))
2474 int index = ipa_get_param_decl_index (info, SSA_NAME_VAR (arg));
2475 if (index >= 0)
2477 bool agg_p;
2478 agg_p = parm_ref_data_pass_through_p (fbi, index, call, arg);
2479 ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
2482 else
2484 gimple *stmt = SSA_NAME_DEF_STMT (arg);
2485 if (is_gimple_assign (stmt))
2486 compute_complex_assign_jump_func (fbi, info, jfunc,
2487 call, stmt, arg, param_type);
2488 else if (gimple_code (stmt) == GIMPLE_PHI)
2489 compute_complex_ancestor_jump_func (fbi, info, jfunc,
2490 call,
2491 as_a <gphi *> (stmt));
2495 /* If ARG is pointer, we cannot use its type to determine the type of aggregate
2496 passed (because type conversions are ignored in gimple). Usually we can
2497 safely get type from function declaration, but in case of K&R prototypes or
2498 variadic functions we can try our luck with type of the pointer passed.
2499 TODO: Since we look for actual initialization of the memory object, we may better
2500 work out the type based on the memory stores we find. */
2501 if (!param_type)
2502 param_type = TREE_TYPE (arg);
2504 if ((jfunc->type != IPA_JF_PASS_THROUGH
2505 || !ipa_get_jf_pass_through_agg_preserved (jfunc))
2506 && (jfunc->type != IPA_JF_ANCESTOR
2507 || !ipa_get_jf_ancestor_agg_preserved (jfunc))
2508 && (AGGREGATE_TYPE_P (TREE_TYPE (arg))
2509 || POINTER_TYPE_P (param_type)))
2510 determine_known_aggregate_parts (fbi, call, arg, param_type, jfunc);
2512 if (!useful_context)
2513 vec_free (args->polymorphic_call_contexts);
2516 /* Compute jump functions for all edges - both direct and indirect - outgoing
2517 from BB. */
2519 static void
2520 ipa_compute_jump_functions_for_bb (struct ipa_func_body_info *fbi, basic_block bb)
2522 struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
2523 int i;
2524 struct cgraph_edge *cs;
2526 FOR_EACH_VEC_ELT_REVERSE (bi->cg_edges, i, cs)
2528 struct cgraph_node *callee = cs->callee;
2530 if (callee)
2532 callee = callee->ultimate_alias_target ();
2533 /* We do not need to bother analyzing calls to unknown functions
2534 unless they may become known during lto/whopr. */
2535 if (!callee->definition && !flag_lto
2536 && !gimple_call_fnspec (cs->call_stmt).known_p ())
2537 continue;
2539 ipa_compute_jump_functions_for_edge (fbi, cs);
2543 /* If STMT looks like a statement loading a value from a member pointer formal
2544 parameter, return that parameter and store the offset of the field to
2545 *OFFSET_P, if it is non-NULL. Otherwise return NULL (but *OFFSET_P still
2546 might be clobbered). If USE_DELTA, then we look for a use of the delta
2547 field rather than the pfn. */
2549 static tree
2550 ipa_get_stmt_member_ptr_load_param (gimple *stmt, bool use_delta,
2551 HOST_WIDE_INT *offset_p)
2553 tree rhs, rec, ref_field, ref_offset, fld, ptr_field, delta_field;
2555 if (!gimple_assign_single_p (stmt))
2556 return NULL_TREE;
2558 rhs = gimple_assign_rhs1 (stmt);
2559 if (TREE_CODE (rhs) == COMPONENT_REF)
2561 ref_field = TREE_OPERAND (rhs, 1);
2562 rhs = TREE_OPERAND (rhs, 0);
2564 else
2565 ref_field = NULL_TREE;
2566 if (TREE_CODE (rhs) != MEM_REF)
2567 return NULL_TREE;
2568 rec = TREE_OPERAND (rhs, 0);
2569 if (TREE_CODE (rec) != ADDR_EXPR)
2570 return NULL_TREE;
2571 rec = TREE_OPERAND (rec, 0);
2572 if (TREE_CODE (rec) != PARM_DECL
2573 || !type_like_member_ptr_p (TREE_TYPE (rec), &ptr_field, &delta_field))
2574 return NULL_TREE;
2575 ref_offset = TREE_OPERAND (rhs, 1);
2577 if (use_delta)
2578 fld = delta_field;
2579 else
2580 fld = ptr_field;
2581 if (offset_p)
2582 *offset_p = int_bit_position (fld);
2584 if (ref_field)
2586 if (integer_nonzerop (ref_offset))
2587 return NULL_TREE;
2588 return ref_field == fld ? rec : NULL_TREE;
2590 else
2591 return tree_int_cst_equal (byte_position (fld), ref_offset) ? rec
2592 : NULL_TREE;
2595 /* Returns true iff T is an SSA_NAME defined by a statement. */
2597 static bool
2598 ipa_is_ssa_with_stmt_def (tree t)
2600 if (TREE_CODE (t) == SSA_NAME
2601 && !SSA_NAME_IS_DEFAULT_DEF (t))
2602 return true;
2603 else
2604 return false;
2607 /* Find the indirect call graph edge corresponding to STMT and mark it as a
2608 call to a parameter number PARAM_INDEX. NODE is the caller. Return the
2609 indirect call graph edge.
2610 If POLYMORPHIC is true record is as a destination of polymorphic call. */
2612 static struct cgraph_edge *
2613 ipa_note_param_call (struct cgraph_node *node, int param_index,
2614 gcall *stmt, bool polymorphic)
2616 struct cgraph_edge *cs;
2618 cs = node->get_edge (stmt);
2619 cs->indirect_info->param_index = param_index;
2620 cs->indirect_info->agg_contents = 0;
2621 cs->indirect_info->member_ptr = 0;
2622 cs->indirect_info->guaranteed_unmodified = 0;
2623 ipa_node_params *info = ipa_node_params_sum->get (node);
2624 ipa_set_param_used_by_indirect_call (info, param_index, true);
2625 if (cs->indirect_info->polymorphic || polymorphic)
2626 ipa_set_param_used_by_polymorphic_call (info, param_index, true);
2627 return cs;
2630 /* Analyze the CALL and examine uses of formal parameters of the caller NODE
2631 (described by INFO). PARMS_AINFO is a pointer to a vector containing
2632 intermediate information about each formal parameter. Currently it checks
2633 whether the call calls a pointer that is a formal parameter and if so, the
2634 parameter is marked with the called flag and an indirect call graph edge
2635 describing the call is created. This is very simple for ordinary pointers
2636 represented in SSA but not-so-nice when it comes to member pointers. The
2637 ugly part of this function does nothing more than trying to match the
2638 pattern of such a call. An example of such a pattern is the gimple dump
2639 below, the call is on the last line:
2641 <bb 2>:
2642 f$__delta_5 = f.__delta;
2643 f$__pfn_24 = f.__pfn;
2646 <bb 2>:
2647 f$__delta_5 = MEM[(struct *)&f];
2648 f$__pfn_24 = MEM[(struct *)&f + 4B];
2650 and a few lines below:
2652 <bb 5>
2653 D.2496_3 = (int) f$__pfn_24;
2654 D.2497_4 = D.2496_3 & 1;
2655 if (D.2497_4 != 0)
2656 goto <bb 3>;
2657 else
2658 goto <bb 4>;
2660 <bb 6>:
2661 D.2500_7 = (unsigned int) f$__delta_5;
2662 D.2501_8 = &S + D.2500_7;
2663 D.2502_9 = (int (*__vtbl_ptr_type) (void) * *) D.2501_8;
2664 D.2503_10 = *D.2502_9;
2665 D.2504_12 = f$__pfn_24 + -1;
2666 D.2505_13 = (unsigned int) D.2504_12;
2667 D.2506_14 = D.2503_10 + D.2505_13;
2668 D.2507_15 = *D.2506_14;
2669 iftmp.11_16 = (String:: *) D.2507_15;
2671 <bb 7>:
2672 # iftmp.11_1 = PHI <iftmp.11_16(3), f$__pfn_24(2)>
2673 D.2500_19 = (unsigned int) f$__delta_5;
2674 D.2508_20 = &S + D.2500_19;
2675 D.2493_21 = iftmp.11_1 (D.2508_20, 4);
2677 Such patterns are results of simple calls to a member pointer:
2679 int doprinting (int (MyString::* f)(int) const)
2681 MyString S ("somestring");
2683 return (S.*f)(4);
2686 Moreover, the function also looks for called pointers loaded from aggregates
2687 passed by value or reference. */
2689 static void
2690 ipa_analyze_indirect_call_uses (struct ipa_func_body_info *fbi, gcall *call,
2691 tree target)
2693 class ipa_node_params *info = fbi->info;
2694 HOST_WIDE_INT offset;
2695 bool by_ref;
2697 if (SSA_NAME_IS_DEFAULT_DEF (target))
2699 tree var = SSA_NAME_VAR (target);
2700 int index = ipa_get_param_decl_index (info, var);
2701 if (index >= 0)
2702 ipa_note_param_call (fbi->node, index, call, false);
2703 return;
2706 int index;
2707 gimple *def = SSA_NAME_DEF_STMT (target);
2708 bool guaranteed_unmodified;
2709 if (gimple_assign_single_p (def)
2710 && ipa_load_from_parm_agg (fbi, info->descriptors, def,
2711 gimple_assign_rhs1 (def), &index, &offset,
2712 NULL, &by_ref, &guaranteed_unmodified))
2714 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
2715 call, false);
2716 cs->indirect_info->offset = offset;
2717 cs->indirect_info->agg_contents = 1;
2718 cs->indirect_info->by_ref = by_ref;
2719 cs->indirect_info->guaranteed_unmodified = guaranteed_unmodified;
2720 return;
2723 /* Now we need to try to match the complex pattern of calling a member
2724 pointer. */
2725 if (gimple_code (def) != GIMPLE_PHI
2726 || gimple_phi_num_args (def) != 2
2727 || !POINTER_TYPE_P (TREE_TYPE (target))
2728 || TREE_CODE (TREE_TYPE (TREE_TYPE (target))) != METHOD_TYPE)
2729 return;
2731 /* First, we need to check whether one of these is a load from a member
2732 pointer that is a parameter to this function. */
2733 tree n1 = PHI_ARG_DEF (def, 0);
2734 tree n2 = PHI_ARG_DEF (def, 1);
2735 if (!ipa_is_ssa_with_stmt_def (n1) || !ipa_is_ssa_with_stmt_def (n2))
2736 return;
2737 gimple *d1 = SSA_NAME_DEF_STMT (n1);
2738 gimple *d2 = SSA_NAME_DEF_STMT (n2);
2740 tree rec;
2741 basic_block bb, virt_bb;
2742 basic_block join = gimple_bb (def);
2743 if ((rec = ipa_get_stmt_member_ptr_load_param (d1, false, &offset)))
2745 if (ipa_get_stmt_member_ptr_load_param (d2, false, NULL))
2746 return;
2748 bb = EDGE_PRED (join, 0)->src;
2749 virt_bb = gimple_bb (d2);
2751 else if ((rec = ipa_get_stmt_member_ptr_load_param (d2, false, &offset)))
2753 bb = EDGE_PRED (join, 1)->src;
2754 virt_bb = gimple_bb (d1);
2756 else
2757 return;
2759 /* Second, we need to check that the basic blocks are laid out in the way
2760 corresponding to the pattern. */
2762 if (!single_pred_p (virt_bb) || !single_succ_p (virt_bb)
2763 || single_pred (virt_bb) != bb
2764 || single_succ (virt_bb) != join)
2765 return;
2767 /* Third, let's see that the branching is done depending on the least
2768 significant bit of the pfn. */
2770 gcond *branch = safe_dyn_cast <gcond *> (*gsi_last_bb (bb));
2771 if (!branch)
2772 return;
2774 if ((gimple_cond_code (branch) != NE_EXPR
2775 && gimple_cond_code (branch) != EQ_EXPR)
2776 || !integer_zerop (gimple_cond_rhs (branch)))
2777 return;
2779 tree cond = gimple_cond_lhs (branch);
2780 if (!ipa_is_ssa_with_stmt_def (cond))
2781 return;
2783 def = SSA_NAME_DEF_STMT (cond);
2784 if (!is_gimple_assign (def)
2785 || gimple_assign_rhs_code (def) != BIT_AND_EXPR
2786 || !integer_onep (gimple_assign_rhs2 (def)))
2787 return;
2789 cond = gimple_assign_rhs1 (def);
2790 if (!ipa_is_ssa_with_stmt_def (cond))
2791 return;
2793 def = SSA_NAME_DEF_STMT (cond);
2795 if (is_gimple_assign (def)
2796 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
2798 cond = gimple_assign_rhs1 (def);
2799 if (!ipa_is_ssa_with_stmt_def (cond))
2800 return;
2801 def = SSA_NAME_DEF_STMT (cond);
2804 tree rec2;
2805 rec2 = ipa_get_stmt_member_ptr_load_param (def,
2806 (TARGET_PTRMEMFUNC_VBIT_LOCATION
2807 == ptrmemfunc_vbit_in_delta),
2808 NULL);
2809 if (rec != rec2)
2810 return;
2812 index = ipa_get_param_decl_index (info, rec);
2813 if (index >= 0
2814 && parm_preserved_before_stmt_p (fbi, index, call, rec))
2816 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
2817 call, false);
2818 cs->indirect_info->offset = offset;
2819 cs->indirect_info->agg_contents = 1;
2820 cs->indirect_info->member_ptr = 1;
2821 cs->indirect_info->guaranteed_unmodified = 1;
2824 return;
2827 /* Analyze a CALL to an OBJ_TYPE_REF which is passed in TARGET and if the
2828 object referenced in the expression is a formal parameter of the caller
2829 FBI->node (described by FBI->info), create a call note for the
2830 statement. */
2832 static void
2833 ipa_analyze_virtual_call_uses (struct ipa_func_body_info *fbi,
2834 gcall *call, tree target)
2836 tree obj = OBJ_TYPE_REF_OBJECT (target);
2837 int index;
2838 HOST_WIDE_INT anc_offset;
2840 if (!flag_devirtualize)
2841 return;
2843 if (TREE_CODE (obj) != SSA_NAME)
2844 return;
2846 class ipa_node_params *info = fbi->info;
2847 if (SSA_NAME_IS_DEFAULT_DEF (obj))
2849 if (TREE_CODE (SSA_NAME_VAR (obj)) != PARM_DECL)
2850 return;
2852 anc_offset = 0;
2853 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (obj));
2854 gcc_assert (index >= 0);
2855 if (detect_type_change_ssa (fbi, obj, obj_type_ref_class (target),
2856 call))
2857 return;
2859 else
2861 gimple *stmt = SSA_NAME_DEF_STMT (obj);
2862 tree expr;
2864 expr = get_ancestor_addr_info (stmt, &obj, &anc_offset);
2865 if (!expr)
2866 return;
2867 index = ipa_get_param_decl_index (info,
2868 SSA_NAME_VAR (TREE_OPERAND (expr, 0)));
2869 gcc_assert (index >= 0);
2870 if (detect_type_change (fbi, obj, expr, obj_type_ref_class (target),
2871 call, anc_offset))
2872 return;
2875 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
2876 call, true);
2877 class cgraph_indirect_call_info *ii = cs->indirect_info;
2878 ii->offset = anc_offset;
2879 ii->otr_token = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target));
2880 ii->otr_type = obj_type_ref_class (target);
2881 ii->polymorphic = 1;
2884 /* Analyze a call statement CALL whether and how it utilizes formal parameters
2885 of the caller (described by INFO). PARMS_AINFO is a pointer to a vector
2886 containing intermediate information about each formal parameter. */
2888 static void
2889 ipa_analyze_call_uses (struct ipa_func_body_info *fbi, gcall *call)
2891 tree target = gimple_call_fn (call);
2893 if (!target
2894 || (TREE_CODE (target) != SSA_NAME
2895 && !virtual_method_call_p (target)))
2896 return;
2898 struct cgraph_edge *cs = fbi->node->get_edge (call);
2899 /* If we previously turned the call into a direct call, there is
2900 no need to analyze. */
2901 if (cs && !cs->indirect_unknown_callee)
2902 return;
2904 if (cs->indirect_info->polymorphic && flag_devirtualize)
2906 tree instance;
2907 tree target = gimple_call_fn (call);
2908 ipa_polymorphic_call_context context (current_function_decl,
2909 target, call, &instance);
2911 gcc_checking_assert (cs->indirect_info->otr_type
2912 == obj_type_ref_class (target));
2913 gcc_checking_assert (cs->indirect_info->otr_token
2914 == tree_to_shwi (OBJ_TYPE_REF_TOKEN (target)));
2916 cs->indirect_info->vptr_changed
2917 = !context.get_dynamic_type (instance,
2918 OBJ_TYPE_REF_OBJECT (target),
2919 obj_type_ref_class (target), call,
2920 &fbi->aa_walk_budget);
2921 cs->indirect_info->context = context;
2924 if (TREE_CODE (target) == SSA_NAME)
2925 ipa_analyze_indirect_call_uses (fbi, call, target);
2926 else if (virtual_method_call_p (target))
2927 ipa_analyze_virtual_call_uses (fbi, call, target);
2931 /* Analyze the call statement STMT with respect to formal parameters (described
2932 in INFO) of caller given by FBI->NODE. Currently it only checks whether
2933 formal parameters are called. */
2935 static void
2936 ipa_analyze_stmt_uses (struct ipa_func_body_info *fbi, gimple *stmt)
2938 if (is_gimple_call (stmt))
2939 ipa_analyze_call_uses (fbi, as_a <gcall *> (stmt));
2942 /* Callback of walk_stmt_load_store_addr_ops for the visit_load.
2943 If OP is a parameter declaration, mark it as used in the info structure
2944 passed in DATA. */
2946 static bool
2947 visit_ref_for_mod_analysis (gimple *, tree op, tree, void *data)
2949 class ipa_node_params *info = (class ipa_node_params *) data;
2951 op = get_base_address (op);
2952 if (op
2953 && TREE_CODE (op) == PARM_DECL)
2955 int index = ipa_get_param_decl_index (info, op);
2956 gcc_assert (index >= 0);
2957 ipa_set_param_used (info, index, true);
2960 return false;
2963 /* Scan the statements in BB and inspect the uses of formal parameters. Store
2964 the findings in various structures of the associated ipa_node_params
2965 structure, such as parameter flags, notes etc. FBI holds various data about
2966 the function being analyzed. */
2968 static void
2969 ipa_analyze_params_uses_in_bb (struct ipa_func_body_info *fbi, basic_block bb)
2971 gimple_stmt_iterator gsi;
2972 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2974 gimple *stmt = gsi_stmt (gsi);
2976 if (is_gimple_debug (stmt))
2977 continue;
2979 ipa_analyze_stmt_uses (fbi, stmt);
2980 walk_stmt_load_store_addr_ops (stmt, fbi->info,
2981 visit_ref_for_mod_analysis,
2982 visit_ref_for_mod_analysis,
2983 visit_ref_for_mod_analysis);
2985 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2986 walk_stmt_load_store_addr_ops (gsi_stmt (gsi), fbi->info,
2987 visit_ref_for_mod_analysis,
2988 visit_ref_for_mod_analysis,
2989 visit_ref_for_mod_analysis);
2992 /* Return true EXPR is a load from a dereference of SSA_NAME NAME. */
2994 static bool
2995 load_from_dereferenced_name (tree expr, tree name)
2997 tree base = get_base_address (expr);
2998 return (TREE_CODE (base) == MEM_REF
2999 && TREE_OPERAND (base, 0) == name);
3002 /* Calculate controlled uses of parameters of NODE. */
3004 static void
3005 ipa_analyze_controlled_uses (struct cgraph_node *node)
3007 ipa_node_params *info = ipa_node_params_sum->get (node);
3009 for (int i = 0; i < ipa_get_param_count (info); i++)
3011 tree parm = ipa_get_param (info, i);
3012 int call_uses = 0;
3013 bool load_dereferenced = false;
3015 /* For SSA regs see if parameter is used. For non-SSA we compute
3016 the flag during modification analysis. */
3017 if (is_gimple_reg (parm))
3019 tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl),
3020 parm);
3021 if (ddef && !has_zero_uses (ddef))
3023 imm_use_iterator imm_iter;
3024 gimple *stmt;
3026 ipa_set_param_used (info, i, true);
3027 FOR_EACH_IMM_USE_STMT (stmt, imm_iter, ddef)
3029 if (is_gimple_debug (stmt))
3030 continue;
3032 int all_stmt_uses = 0;
3033 use_operand_p use_p;
3034 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
3035 all_stmt_uses++;
3037 if (is_gimple_call (stmt))
3039 if (gimple_call_internal_p (stmt))
3041 call_uses = IPA_UNDESCRIBED_USE;
3042 break;
3044 int recognized_stmt_uses;
3045 if (gimple_call_fn (stmt) == ddef)
3046 recognized_stmt_uses = 1;
3047 else
3048 recognized_stmt_uses = 0;
3049 unsigned arg_count = gimple_call_num_args (stmt);
3050 for (unsigned i = 0; i < arg_count; i++)
3052 tree arg = gimple_call_arg (stmt, i);
3053 if (arg == ddef)
3054 recognized_stmt_uses++;
3055 else if (load_from_dereferenced_name (arg, ddef))
3057 load_dereferenced = true;
3058 recognized_stmt_uses++;
3062 if (recognized_stmt_uses != all_stmt_uses)
3064 call_uses = IPA_UNDESCRIBED_USE;
3065 break;
3067 if (call_uses >= 0)
3068 call_uses += all_stmt_uses;
3070 else if (gimple_assign_single_p (stmt))
3072 tree rhs = gimple_assign_rhs1 (stmt);
3073 if (all_stmt_uses != 1
3074 || !load_from_dereferenced_name (rhs, ddef))
3076 call_uses = IPA_UNDESCRIBED_USE;
3077 break;
3079 load_dereferenced = true;
3081 else
3083 call_uses = IPA_UNDESCRIBED_USE;
3084 break;
3088 else
3089 call_uses = 0;
3091 else
3092 call_uses = IPA_UNDESCRIBED_USE;
3093 ipa_set_controlled_uses (info, i, call_uses);
3094 ipa_set_param_load_dereferenced (info, i, load_dereferenced);
3098 /* Free stuff in BI. */
3100 static void
3101 free_ipa_bb_info (struct ipa_bb_info *bi)
3103 bi->cg_edges.release ();
3104 bi->param_aa_statuses.release ();
3107 /* Dominator walker driving the analysis. */
3109 class analysis_dom_walker : public dom_walker
3111 public:
3112 analysis_dom_walker (struct ipa_func_body_info *fbi)
3113 : dom_walker (CDI_DOMINATORS), m_fbi (fbi) {}
3115 edge before_dom_children (basic_block) final override;
3117 private:
3118 struct ipa_func_body_info *m_fbi;
3121 edge
3122 analysis_dom_walker::before_dom_children (basic_block bb)
3124 ipa_analyze_params_uses_in_bb (m_fbi, bb);
3125 ipa_compute_jump_functions_for_bb (m_fbi, bb);
3126 return NULL;
3129 /* Release body info FBI. */
3131 void
3132 ipa_release_body_info (struct ipa_func_body_info *fbi)
3134 int i;
3135 struct ipa_bb_info *bi;
3137 FOR_EACH_VEC_ELT (fbi->bb_infos, i, bi)
3138 free_ipa_bb_info (bi);
3139 fbi->bb_infos.release ();
3142 /* Initialize the array describing properties of formal parameters
3143 of NODE, analyze their uses and compute jump functions associated
3144 with actual arguments of calls from within NODE. */
3146 void
3147 ipa_analyze_node (struct cgraph_node *node)
3149 struct ipa_func_body_info fbi;
3150 class ipa_node_params *info;
3152 ipa_check_create_node_params ();
3153 ipa_check_create_edge_args ();
3154 info = ipa_node_params_sum->get_create (node);
3156 if (info->analysis_done)
3157 return;
3158 info->analysis_done = 1;
3160 if (ipa_func_spec_opts_forbid_analysis_p (node)
3161 || (count_formal_params (node->decl)
3162 >= (1 << IPA_PROP_ARG_INDEX_LIMIT_BITS)))
3164 gcc_assert (!ipa_get_param_count (info));
3165 return;
3168 struct function *func = DECL_STRUCT_FUNCTION (node->decl);
3169 push_cfun (func);
3170 calculate_dominance_info (CDI_DOMINATORS);
3171 ipa_initialize_node_params (node);
3172 ipa_analyze_controlled_uses (node);
3174 fbi.node = node;
3175 fbi.info = info;
3176 fbi.bb_infos = vNULL;
3177 fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
3178 fbi.param_count = ipa_get_param_count (info);
3179 fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps);
3181 for (struct cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
3183 ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
3184 bi->cg_edges.safe_push (cs);
3187 for (struct cgraph_edge *cs = node->indirect_calls; cs; cs = cs->next_callee)
3189 ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
3190 bi->cg_edges.safe_push (cs);
3193 enable_ranger (cfun, false);
3194 analysis_dom_walker (&fbi).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
3195 disable_ranger (cfun);
3197 ipa_release_body_info (&fbi);
3198 free_dominance_info (CDI_DOMINATORS);
3199 pop_cfun ();
3202 /* Update the jump functions associated with call graph edge E when the call
3203 graph edge CS is being inlined, assuming that E->caller is already (possibly
3204 indirectly) inlined into CS->callee and that E has not been inlined. */
3206 static void
3207 update_jump_functions_after_inlining (struct cgraph_edge *cs,
3208 struct cgraph_edge *e)
3210 ipa_edge_args *top = ipa_edge_args_sum->get (cs);
3211 ipa_edge_args *args = ipa_edge_args_sum->get (e);
3212 if (!args)
3213 return;
3214 int count = ipa_get_cs_argument_count (args);
3215 int i;
3217 for (i = 0; i < count; i++)
3219 struct ipa_jump_func *dst = ipa_get_ith_jump_func (args, i);
3220 class ipa_polymorphic_call_context *dst_ctx
3221 = ipa_get_ith_polymorhic_call_context (args, i);
3223 if (dst->agg.items)
3225 struct ipa_agg_jf_item *item;
3226 int j;
3228 FOR_EACH_VEC_ELT (*dst->agg.items, j, item)
3230 int dst_fid;
3231 struct ipa_jump_func *src;
3233 if (item->jftype != IPA_JF_PASS_THROUGH
3234 && item->jftype != IPA_JF_LOAD_AGG)
3235 continue;
3237 dst_fid = item->value.pass_through.formal_id;
3238 if (!top || dst_fid >= ipa_get_cs_argument_count (top))
3240 item->jftype = IPA_JF_UNKNOWN;
3241 continue;
3244 item->value.pass_through.formal_id = -1;
3245 src = ipa_get_ith_jump_func (top, dst_fid);
3246 if (src->type == IPA_JF_CONST)
3248 if (item->jftype == IPA_JF_PASS_THROUGH
3249 && item->value.pass_through.operation == NOP_EXPR)
3251 item->jftype = IPA_JF_CONST;
3252 item->value.constant = src->value.constant.value;
3253 continue;
3256 else if (src->type == IPA_JF_PASS_THROUGH
3257 && src->value.pass_through.operation == NOP_EXPR)
3259 if (item->jftype == IPA_JF_PASS_THROUGH
3260 || !item->value.load_agg.by_ref
3261 || src->value.pass_through.agg_preserved)
3262 item->value.pass_through.formal_id
3263 = src->value.pass_through.formal_id;
3265 else if (src->type == IPA_JF_ANCESTOR)
3267 if (item->jftype == IPA_JF_PASS_THROUGH)
3269 if (!src->value.ancestor.offset)
3270 item->value.pass_through.formal_id
3271 = src->value.ancestor.formal_id;
3273 else if (src->value.ancestor.agg_preserved)
3275 gcc_checking_assert (item->value.load_agg.by_ref);
3277 item->value.pass_through.formal_id
3278 = src->value.ancestor.formal_id;
3279 item->value.load_agg.offset
3280 += src->value.ancestor.offset;
3284 if (item->value.pass_through.formal_id < 0)
3285 item->jftype = IPA_JF_UNKNOWN;
3289 if (!top)
3291 ipa_set_jf_unknown (dst);
3292 continue;
3295 if (dst->type == IPA_JF_ANCESTOR)
3297 struct ipa_jump_func *src;
3298 int dst_fid = dst->value.ancestor.formal_id;
3299 class ipa_polymorphic_call_context *src_ctx
3300 = ipa_get_ith_polymorhic_call_context (top, dst_fid);
3302 /* Variable number of arguments can cause havoc if we try to access
3303 one that does not exist in the inlined edge. So make sure we
3304 don't. */
3305 if (dst_fid >= ipa_get_cs_argument_count (top))
3307 ipa_set_jf_unknown (dst);
3308 continue;
3311 src = ipa_get_ith_jump_func (top, dst_fid);
3313 if (src_ctx && !src_ctx->useless_p ())
3315 class ipa_polymorphic_call_context ctx = *src_ctx;
3317 /* TODO: Make type preserved safe WRT contexts. */
3318 if (!ipa_get_jf_ancestor_type_preserved (dst))
3319 ctx.possible_dynamic_type_change (e->in_polymorphic_cdtor);
3320 ctx.offset_by (dst->value.ancestor.offset);
3321 if (!ctx.useless_p ())
3323 if (!dst_ctx)
3325 vec_safe_grow_cleared (args->polymorphic_call_contexts,
3326 count, true);
3327 dst_ctx = ipa_get_ith_polymorhic_call_context (args, i);
3330 dst_ctx->combine_with (ctx);
3334 /* Parameter and argument in ancestor jump function must be pointer
3335 type, which means access to aggregate must be by-reference. */
3336 gcc_assert (!src->agg.items || src->agg.by_ref);
3338 if (src->agg.items && dst->value.ancestor.agg_preserved)
3340 struct ipa_agg_jf_item *item;
3341 int j;
3343 /* Currently we do not produce clobber aggregate jump functions,
3344 replace with merging when we do. */
3345 gcc_assert (!dst->agg.items);
3347 dst->agg.items = vec_safe_copy (src->agg.items);
3348 dst->agg.by_ref = src->agg.by_ref;
3349 FOR_EACH_VEC_SAFE_ELT (dst->agg.items, j, item)
3350 item->offset -= dst->value.ancestor.offset;
3353 if (src->type == IPA_JF_PASS_THROUGH
3354 && src->value.pass_through.operation == NOP_EXPR)
3356 dst->value.ancestor.formal_id = src->value.pass_through.formal_id;
3357 dst->value.ancestor.agg_preserved &=
3358 src->value.pass_through.agg_preserved;
3360 else if (src->type == IPA_JF_ANCESTOR)
3362 dst->value.ancestor.formal_id = src->value.ancestor.formal_id;
3363 dst->value.ancestor.offset += src->value.ancestor.offset;
3364 dst->value.ancestor.agg_preserved &=
3365 src->value.ancestor.agg_preserved;
3366 dst->value.ancestor.keep_null |= src->value.ancestor.keep_null;
3368 else
3369 ipa_set_jf_unknown (dst);
3371 else if (dst->type == IPA_JF_PASS_THROUGH)
3373 struct ipa_jump_func *src;
3374 /* We must check range due to calls with variable number of arguments
3375 and we cannot combine jump functions with operations. */
3376 if (dst->value.pass_through.operation == NOP_EXPR
3377 && (top && dst->value.pass_through.formal_id
3378 < ipa_get_cs_argument_count (top)))
3380 int dst_fid = dst->value.pass_through.formal_id;
3381 src = ipa_get_ith_jump_func (top, dst_fid);
3382 bool dst_agg_p = ipa_get_jf_pass_through_agg_preserved (dst);
3383 class ipa_polymorphic_call_context *src_ctx
3384 = ipa_get_ith_polymorhic_call_context (top, dst_fid);
3386 if (src_ctx && !src_ctx->useless_p ())
3388 class ipa_polymorphic_call_context ctx = *src_ctx;
3390 /* TODO: Make type preserved safe WRT contexts. */
3391 if (!ipa_get_jf_pass_through_type_preserved (dst))
3392 ctx.possible_dynamic_type_change (e->in_polymorphic_cdtor);
3393 if (!ctx.useless_p ())
3395 if (!dst_ctx)
3397 vec_safe_grow_cleared (args->polymorphic_call_contexts,
3398 count, true);
3399 dst_ctx = ipa_get_ith_polymorhic_call_context (args, i);
3401 dst_ctx->combine_with (ctx);
3404 switch (src->type)
3406 case IPA_JF_UNKNOWN:
3407 ipa_set_jf_unknown (dst);
3408 break;
3409 case IPA_JF_CONST:
3411 bool rd = ipa_get_jf_pass_through_refdesc_decremented (dst);
3412 ipa_set_jf_cst_copy (dst, src);
3413 if (rd)
3414 ipa_zap_jf_refdesc (dst);
3417 break;
3419 case IPA_JF_PASS_THROUGH:
3421 int formal_id = ipa_get_jf_pass_through_formal_id (src);
3422 enum tree_code operation;
3423 operation = ipa_get_jf_pass_through_operation (src);
3425 if (operation == NOP_EXPR)
3427 bool agg_p;
3428 agg_p = dst_agg_p
3429 && ipa_get_jf_pass_through_agg_preserved (src);
3430 ipa_set_jf_simple_pass_through (dst, formal_id, agg_p);
3432 else if (TREE_CODE_CLASS (operation) == tcc_unary)
3433 ipa_set_jf_unary_pass_through (dst, formal_id, operation);
3434 else
3436 tree operand = ipa_get_jf_pass_through_operand (src);
3437 ipa_set_jf_arith_pass_through (dst, formal_id, operand,
3438 operation);
3440 break;
3442 case IPA_JF_ANCESTOR:
3444 bool agg_p;
3445 agg_p = dst_agg_p
3446 && ipa_get_jf_ancestor_agg_preserved (src);
3447 ipa_set_ancestor_jf (dst,
3448 ipa_get_jf_ancestor_offset (src),
3449 ipa_get_jf_ancestor_formal_id (src),
3450 agg_p,
3451 ipa_get_jf_ancestor_keep_null (src));
3452 break;
3454 default:
3455 gcc_unreachable ();
3458 if (src->agg.items
3459 && (dst_agg_p || !src->agg.by_ref))
3461 /* Currently we do not produce clobber aggregate jump
3462 functions, replace with merging when we do. */
3463 gcc_assert (!dst->agg.items);
3465 dst->agg.by_ref = src->agg.by_ref;
3466 dst->agg.items = vec_safe_copy (src->agg.items);
3469 else
3470 ipa_set_jf_unknown (dst);
3475 /* If TARGET is an addr_expr of a function declaration, make it the
3476 (SPECULATIVE)destination of an indirect edge IE and return the edge.
3477 Otherwise, return NULL. */
3479 struct cgraph_edge *
3480 ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
3481 bool speculative)
3483 struct cgraph_node *callee;
3484 bool unreachable = false;
3486 if (TREE_CODE (target) == ADDR_EXPR)
3487 target = TREE_OPERAND (target, 0);
3488 if (TREE_CODE (target) != FUNCTION_DECL)
3490 target = canonicalize_constructor_val (target, NULL);
3491 if (!target || TREE_CODE (target) != FUNCTION_DECL)
3493 /* Member pointer call that goes through a VMT lookup. */
3494 if (ie->indirect_info->member_ptr
3495 /* Or if target is not an invariant expression and we do not
3496 know if it will evaulate to function at runtime.
3497 This can happen when folding through &VAR, where &VAR
3498 is IP invariant, but VAR itself is not.
3500 TODO: Revisit this when GCC 5 is branched. It seems that
3501 member_ptr check is not needed and that we may try to fold
3502 the expression and see if VAR is readonly. */
3503 || !is_gimple_ip_invariant (target))
3505 if (dump_enabled_p ())
3507 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
3508 "discovered direct call non-invariant %s\n",
3509 ie->caller->dump_name ());
3511 return NULL;
3515 if (dump_enabled_p ())
3517 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
3518 "discovered direct call to non-function in %s, "
3519 "making it __builtin_unreachable\n",
3520 ie->caller->dump_name ());
3523 target = builtin_decl_unreachable ();
3524 callee = cgraph_node::get_create (target);
3525 unreachable = true;
3527 else
3528 callee = cgraph_node::get (target);
3530 else
3531 callee = cgraph_node::get (target);
3533 /* Because may-edges are not explicitely represented and vtable may be external,
3534 we may create the first reference to the object in the unit. */
3535 if (!callee || callee->inlined_to)
3538 /* We are better to ensure we can refer to it.
3539 In the case of static functions we are out of luck, since we already
3540 removed its body. In the case of public functions we may or may
3541 not introduce the reference. */
3542 if (!canonicalize_constructor_val (target, NULL)
3543 || !TREE_PUBLIC (target))
3545 if (dump_file)
3546 fprintf (dump_file, "ipa-prop: Discovered call to a known target "
3547 "(%s -> %s) but cannot refer to it. Giving up.\n",
3548 ie->caller->dump_name (),
3549 ie->callee->dump_name ());
3550 return NULL;
3552 callee = cgraph_node::get_create (target);
3555 /* If the edge is already speculated. */
3556 if (speculative && ie->speculative)
3558 if (dump_file)
3560 cgraph_edge *e2 = ie->speculative_call_for_target (callee);
3561 if (!e2)
3563 if (dump_file)
3564 fprintf (dump_file, "ipa-prop: Discovered call to a "
3565 "speculative target (%s -> %s) but the call is "
3566 "already speculated to different target. "
3567 "Giving up.\n",
3568 ie->caller->dump_name (), callee->dump_name ());
3570 else
3572 if (dump_file)
3573 fprintf (dump_file,
3574 "ipa-prop: Discovered call to a speculative target "
3575 "(%s -> %s) this agree with previous speculation.\n",
3576 ie->caller->dump_name (), callee->dump_name ());
3579 return NULL;
3582 if (!dbg_cnt (devirt))
3583 return NULL;
3585 ipa_check_create_node_params ();
3587 /* We cannot make edges to inline clones. It is bug that someone removed
3588 the cgraph node too early. */
3589 gcc_assert (!callee->inlined_to);
3591 if (dump_file && !unreachable)
3593 fprintf (dump_file, "ipa-prop: Discovered %s call to a %s target "
3594 "(%s -> %s), for stmt ",
3595 ie->indirect_info->polymorphic ? "a virtual" : "an indirect",
3596 speculative ? "speculative" : "known",
3597 ie->caller->dump_name (),
3598 callee->dump_name ());
3599 if (ie->call_stmt)
3600 print_gimple_stmt (dump_file, ie->call_stmt, 2, TDF_SLIM);
3601 else
3602 fprintf (dump_file, "with uid %i\n", ie->lto_stmt_uid);
3604 if (dump_enabled_p ())
3606 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
3607 "converting indirect call in %s to direct call to %s\n",
3608 ie->caller->dump_name (), callee->dump_name ());
3610 if (!speculative)
3612 struct cgraph_edge *orig = ie;
3613 ie = cgraph_edge::make_direct (ie, callee);
3614 /* If we resolved speculative edge the cost is already up to date
3615 for direct call (adjusted by inline_edge_duplication_hook). */
3616 if (ie == orig)
3618 ipa_call_summary *es = ipa_call_summaries->get (ie);
3619 es->call_stmt_size -= (eni_size_weights.indirect_call_cost
3620 - eni_size_weights.call_cost);
3621 es->call_stmt_time -= (eni_time_weights.indirect_call_cost
3622 - eni_time_weights.call_cost);
3625 else
3627 if (!callee->can_be_discarded_p ())
3629 cgraph_node *alias;
3630 alias = dyn_cast<cgraph_node *> (callee->noninterposable_alias ());
3631 if (alias)
3632 callee = alias;
3634 /* make_speculative will update ie's cost to direct call cost. */
3635 ie = ie->make_speculative
3636 (callee, ie->count.apply_scale (8, 10));
3639 return ie;
3642 /* Attempt to locate an interprocedural constant at a given REQ_OFFSET in
3643 CONSTRUCTOR and return it. Return NULL if the search fails for some
3644 reason. */
3646 static tree
3647 find_constructor_constant_at_offset (tree constructor, HOST_WIDE_INT req_offset)
3649 tree type = TREE_TYPE (constructor);
3650 if (TREE_CODE (type) != ARRAY_TYPE
3651 && TREE_CODE (type) != RECORD_TYPE)
3652 return NULL;
3654 unsigned ix;
3655 tree index, val;
3656 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (constructor), ix, index, val)
3658 HOST_WIDE_INT elt_offset;
3659 if (TREE_CODE (type) == ARRAY_TYPE)
3661 offset_int off;
3662 tree unit_size = TYPE_SIZE_UNIT (TREE_TYPE (type));
3663 gcc_assert (TREE_CODE (unit_size) == INTEGER_CST);
3665 if (index)
3667 if (TREE_CODE (index) == RANGE_EXPR)
3668 off = wi::to_offset (TREE_OPERAND (index, 0));
3669 else
3670 off = wi::to_offset (index);
3671 if (TYPE_DOMAIN (type) && TYPE_MIN_VALUE (TYPE_DOMAIN (type)))
3673 tree low_bound = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
3674 gcc_assert (TREE_CODE (unit_size) == INTEGER_CST);
3675 off = wi::sext (off - wi::to_offset (low_bound),
3676 TYPE_PRECISION (TREE_TYPE (index)));
3678 off *= wi::to_offset (unit_size);
3679 /* ??? Handle more than just the first index of a
3680 RANGE_EXPR. */
3682 else
3683 off = wi::to_offset (unit_size) * ix;
3685 off = wi::lshift (off, LOG2_BITS_PER_UNIT);
3686 if (!wi::fits_shwi_p (off) || wi::neg_p (off))
3687 continue;
3688 elt_offset = off.to_shwi ();
3690 else if (TREE_CODE (type) == RECORD_TYPE)
3692 gcc_checking_assert (index && TREE_CODE (index) == FIELD_DECL);
3693 if (DECL_BIT_FIELD (index))
3694 continue;
3695 elt_offset = int_bit_position (index);
3697 else
3698 gcc_unreachable ();
3700 if (elt_offset > req_offset)
3701 return NULL;
3703 if (TREE_CODE (val) == CONSTRUCTOR)
3704 return find_constructor_constant_at_offset (val,
3705 req_offset - elt_offset);
3707 if (elt_offset == req_offset
3708 && is_gimple_reg_type (TREE_TYPE (val))
3709 && is_gimple_ip_invariant (val))
3710 return val;
3712 return NULL;
3715 /* Check whether SCALAR could be used to look up an aggregate interprocedural
3716 invariant from a static constructor and if so, return it. Otherwise return
3717 NULL. */
3719 tree
3720 ipa_find_agg_cst_from_init (tree scalar, HOST_WIDE_INT offset, bool by_ref)
3722 if (by_ref)
3724 if (TREE_CODE (scalar) != ADDR_EXPR)
3725 return NULL;
3726 scalar = TREE_OPERAND (scalar, 0);
3729 if (!VAR_P (scalar)
3730 || !is_global_var (scalar)
3731 || !TREE_READONLY (scalar)
3732 || !DECL_INITIAL (scalar)
3733 || TREE_CODE (DECL_INITIAL (scalar)) != CONSTRUCTOR)
3734 return NULL;
3736 return find_constructor_constant_at_offset (DECL_INITIAL (scalar), offset);
3739 /* Retrieve value from AGG_JFUNC for the given OFFSET or return NULL if there
3740 is none. BY_REF specifies whether the value has to be passed by reference
3741 or by value. */
3743 static tree
3744 ipa_find_agg_cst_from_jfunc_items (struct ipa_agg_jump_function *agg_jfunc,
3745 ipa_node_params *src_info,
3746 cgraph_node *src_node,
3747 HOST_WIDE_INT offset, bool by_ref)
3749 if (by_ref != agg_jfunc->by_ref)
3750 return NULL_TREE;
3752 for (const ipa_agg_jf_item &item : agg_jfunc->items)
3753 if (item.offset == offset)
3754 return ipa_agg_value_from_jfunc (src_info, src_node, &item);
3756 return NULL_TREE;
3759 /* Remove a reference to SYMBOL from the list of references of a node given by
3760 reference description RDESC. Return true if the reference has been
3761 successfully found and removed. */
3763 static bool
3764 remove_described_reference (symtab_node *symbol, struct ipa_cst_ref_desc *rdesc)
3766 struct ipa_ref *to_del;
3767 struct cgraph_edge *origin;
3769 origin = rdesc->cs;
3770 if (!origin)
3771 return false;
3772 to_del = origin->caller->find_reference (symbol, origin->call_stmt,
3773 origin->lto_stmt_uid, IPA_REF_ADDR);
3774 if (!to_del)
3775 return false;
3777 to_del->remove_reference ();
3778 if (dump_file)
3779 fprintf (dump_file, "ipa-prop: Removed a reference from %s to %s.\n",
3780 origin->caller->dump_name (), symbol->dump_name ());
3781 return true;
3784 /* If JFUNC has a reference description with refcount different from
3785 IPA_UNDESCRIBED_USE, return the reference description, otherwise return
3786 NULL. JFUNC must be a constant jump function. */
3788 static struct ipa_cst_ref_desc *
3789 jfunc_rdesc_usable (struct ipa_jump_func *jfunc)
3791 struct ipa_cst_ref_desc *rdesc = ipa_get_jf_constant_rdesc (jfunc);
3792 if (rdesc && rdesc->refcount != IPA_UNDESCRIBED_USE)
3793 return rdesc;
3794 else
3795 return NULL;
3798 /* If the value of constant jump function JFUNC is an address of a function
3799 declaration, return the associated call graph node. Otherwise return
3800 NULL. */
3802 static symtab_node *
3803 symtab_node_for_jfunc (struct ipa_jump_func *jfunc)
3805 gcc_checking_assert (jfunc->type == IPA_JF_CONST);
3806 tree cst = ipa_get_jf_constant (jfunc);
3807 if (TREE_CODE (cst) != ADDR_EXPR
3808 || (TREE_CODE (TREE_OPERAND (cst, 0)) != FUNCTION_DECL
3809 && TREE_CODE (TREE_OPERAND (cst, 0)) != VAR_DECL))
3810 return NULL;
3812 return symtab_node::get (TREE_OPERAND (cst, 0));
3816 /* If JFUNC is a constant jump function with a usable rdesc, decrement its
3817 refcount and if it hits zero, remove reference to SYMBOL from the caller of
3818 the edge specified in the rdesc. Return false if either the symbol or the
3819 reference could not be found, otherwise return true. */
3821 static bool
3822 try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc)
3824 struct ipa_cst_ref_desc *rdesc;
3825 if (jfunc->type == IPA_JF_CONST
3826 && (rdesc = jfunc_rdesc_usable (jfunc))
3827 && --rdesc->refcount == 0)
3829 symtab_node *symbol = symtab_node_for_jfunc (jfunc);
3830 if (!symbol)
3831 return false;
3833 return remove_described_reference (symbol, rdesc);
3835 return true;
3838 /* Try to find a destination for indirect edge IE that corresponds to a simple
3839 call or a call of a member function pointer and where the destination is a
3840 pointer formal parameter described by jump function JFUNC. TARGET_TYPE is
3841 the type of the parameter to which the result of JFUNC is passed. If it can
3842 be determined, return the newly direct edge, otherwise return NULL.
3843 NEW_ROOT and NEW_ROOT_INFO is the node and its info that JFUNC lattices are
3844 relative to. */
3846 static struct cgraph_edge *
3847 try_make_edge_direct_simple_call (struct cgraph_edge *ie,
3848 struct ipa_jump_func *jfunc, tree target_type,
3849 struct cgraph_node *new_root,
3850 class ipa_node_params *new_root_info)
3852 struct cgraph_edge *cs;
3853 tree target = NULL_TREE;
3854 bool agg_contents = ie->indirect_info->agg_contents;
3855 tree scalar = ipa_value_from_jfunc (new_root_info, jfunc, target_type);
3856 if (agg_contents)
3858 if (scalar)
3859 target = ipa_find_agg_cst_from_init (scalar, ie->indirect_info->offset,
3860 ie->indirect_info->by_ref);
3861 if (!target && ie->indirect_info->guaranteed_unmodified)
3862 target = ipa_find_agg_cst_from_jfunc_items (&jfunc->agg, new_root_info,
3863 new_root,
3864 ie->indirect_info->offset,
3865 ie->indirect_info->by_ref);
3867 else
3868 target = scalar;
3869 if (!target)
3870 return NULL;
3871 cs = ipa_make_edge_direct_to_target (ie, target);
3873 if (cs && !agg_contents)
3875 bool ok;
3876 gcc_checking_assert (cs->callee
3877 && (cs != ie
3878 || jfunc->type != IPA_JF_CONST
3879 || !symtab_node_for_jfunc (jfunc)
3880 || cs->callee == symtab_node_for_jfunc (jfunc)));
3881 ok = try_decrement_rdesc_refcount (jfunc);
3882 gcc_checking_assert (ok);
3885 return cs;
3888 /* Return the target to be used in cases of impossible devirtualization. IE
3889 and target (the latter can be NULL) are dumped when dumping is enabled. */
3891 tree
3892 ipa_impossible_devirt_target (struct cgraph_edge *ie, tree target)
3894 if (dump_file)
3896 if (target)
3897 fprintf (dump_file,
3898 "Type inconsistent devirtualization: %s->%s\n",
3899 ie->caller->dump_name (),
3900 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (target)));
3901 else
3902 fprintf (dump_file,
3903 "No devirtualization target in %s\n",
3904 ie->caller->dump_name ());
3906 tree new_target = builtin_decl_unreachable ();
3907 cgraph_node::get_create (new_target);
3908 return new_target;
3911 /* Try to find a destination for indirect edge IE that corresponds to a virtual
3912 call based on a formal parameter which is described by jump function JFUNC
3913 and if it can be determined, make it direct and return the direct edge.
3914 Otherwise, return NULL. CTX describes the polymorphic context that the
3915 parameter the call is based on brings along with it. NEW_ROOT and
3916 NEW_ROOT_INFO is the node and its info that JFUNC lattices are relative
3917 to. */
3919 static struct cgraph_edge *
3920 try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
3921 struct ipa_jump_func *jfunc,
3922 class ipa_polymorphic_call_context ctx,
3923 struct cgraph_node *new_root,
3924 class ipa_node_params *new_root_info)
3926 tree target = NULL;
3927 bool speculative = false;
3929 if (!opt_for_fn (ie->caller->decl, flag_devirtualize))
3930 return NULL;
3932 gcc_assert (!ie->indirect_info->by_ref);
3934 /* Try to do lookup via known virtual table pointer value. */
3935 if (!ie->indirect_info->vptr_changed
3936 || opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively))
3938 tree vtable;
3939 unsigned HOST_WIDE_INT offset;
3940 tree t = NULL_TREE;
3941 if (jfunc->type == IPA_JF_CONST)
3942 t = ipa_find_agg_cst_from_init (ipa_get_jf_constant (jfunc),
3943 ie->indirect_info->offset, true);
3944 if (!t)
3945 t = ipa_find_agg_cst_from_jfunc_items (&jfunc->agg, new_root_info,
3946 new_root,
3947 ie->indirect_info->offset, true);
3948 if (t && vtable_pointer_value_to_vtable (t, &vtable, &offset))
3950 bool can_refer;
3951 t = gimple_get_virt_method_for_vtable (ie->indirect_info->otr_token,
3952 vtable, offset, &can_refer);
3953 if (can_refer)
3955 if (!t
3956 || fndecl_built_in_p (t, BUILT_IN_UNREACHABLE,
3957 BUILT_IN_UNREACHABLE_TRAP)
3958 || !possible_polymorphic_call_target_p
3959 (ie, cgraph_node::get (t)))
3961 /* Do not speculate builtin_unreachable, it is stupid! */
3962 if (!ie->indirect_info->vptr_changed)
3963 target = ipa_impossible_devirt_target (ie, target);
3964 else
3965 target = NULL;
3967 else
3969 target = t;
3970 speculative = ie->indirect_info->vptr_changed;
3976 ipa_polymorphic_call_context ie_context (ie);
3977 vec <cgraph_node *>targets;
3978 bool final;
3980 ctx.offset_by (ie->indirect_info->offset);
3981 if (ie->indirect_info->vptr_changed)
3982 ctx.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
3983 ie->indirect_info->otr_type);
3984 ctx.combine_with (ie_context, ie->indirect_info->otr_type);
3985 targets = possible_polymorphic_call_targets
3986 (ie->indirect_info->otr_type,
3987 ie->indirect_info->otr_token,
3988 ctx, &final);
3989 if (final && targets.length () <= 1)
3991 speculative = false;
3992 if (targets.length () == 1)
3993 target = targets[0]->decl;
3994 else
3995 target = ipa_impossible_devirt_target (ie, NULL_TREE);
3997 else if (!target && opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively)
3998 && !ie->speculative && ie->maybe_hot_p ())
4000 cgraph_node *n;
4001 n = try_speculative_devirtualization (ie->indirect_info->otr_type,
4002 ie->indirect_info->otr_token,
4003 ie->indirect_info->context);
4004 if (n)
4006 target = n->decl;
4007 speculative = true;
4011 if (target)
4013 if (!possible_polymorphic_call_target_p
4014 (ie, cgraph_node::get_create (target)))
4016 if (speculative)
4017 return NULL;
4018 target = ipa_impossible_devirt_target (ie, target);
4020 return ipa_make_edge_direct_to_target (ie, target, speculative);
4022 else
4023 return NULL;
4026 /* Update the param called notes associated with NODE when CS is being inlined,
4027 assuming NODE is (potentially indirectly) inlined into CS->callee.
4028 Moreover, if the callee is discovered to be constant, create a new cgraph
4029 edge for it. Newly discovered indirect edges will be added to *NEW_EDGES,
4030 unless NEW_EDGES is NULL. Return true iff a new edge(s) were created. */
4032 static bool
4033 update_indirect_edges_after_inlining (struct cgraph_edge *cs,
4034 struct cgraph_node *node,
4035 vec<cgraph_edge *> *new_edges)
4037 class ipa_edge_args *top;
4038 struct cgraph_edge *ie, *next_ie, *new_direct_edge;
4039 struct cgraph_node *new_root;
4040 class ipa_node_params *new_root_info, *inlined_node_info;
4041 bool res = false;
4043 ipa_check_create_edge_args ();
4044 top = ipa_edge_args_sum->get (cs);
4045 new_root = cs->caller->inlined_to
4046 ? cs->caller->inlined_to : cs->caller;
4047 new_root_info = ipa_node_params_sum->get (new_root);
4048 inlined_node_info = ipa_node_params_sum->get (cs->callee->function_symbol ());
4050 for (ie = node->indirect_calls; ie; ie = next_ie)
4052 class cgraph_indirect_call_info *ici = ie->indirect_info;
4053 struct ipa_jump_func *jfunc;
4054 int param_index;
4056 next_ie = ie->next_callee;
4058 if (ici->param_index == -1)
4059 continue;
4061 /* We must check range due to calls with variable number of arguments: */
4062 if (!top || ici->param_index >= ipa_get_cs_argument_count (top))
4064 ici->param_index = -1;
4065 continue;
4068 param_index = ici->param_index;
4069 jfunc = ipa_get_ith_jump_func (top, param_index);
4071 auto_vec<cgraph_node *, 4> spec_targets;
4072 if (ie->speculative)
4073 for (cgraph_edge *direct = ie->first_speculative_call_target ();
4074 direct;
4075 direct = direct->next_speculative_call_target ())
4076 spec_targets.safe_push (direct->callee);
4078 if (!opt_for_fn (node->decl, flag_indirect_inlining))
4079 new_direct_edge = NULL;
4080 else if (ici->polymorphic)
4082 ipa_polymorphic_call_context ctx;
4083 ctx = ipa_context_from_jfunc (new_root_info, cs, param_index, jfunc);
4084 new_direct_edge = try_make_edge_direct_virtual_call (ie, jfunc, ctx,
4085 new_root,
4086 new_root_info);
4088 else
4090 tree target_type = ipa_get_type (inlined_node_info, param_index);
4091 new_direct_edge = try_make_edge_direct_simple_call (ie, jfunc,
4092 target_type,
4093 new_root,
4094 new_root_info);
4097 /* If speculation was removed, then we need to do nothing. */
4098 if (new_direct_edge && new_direct_edge != ie
4099 && spec_targets.contains (new_direct_edge->callee))
4101 new_direct_edge->indirect_inlining_edge = 1;
4102 res = true;
4103 if (!new_direct_edge->speculative)
4104 continue;
4106 else if (new_direct_edge)
4108 new_direct_edge->indirect_inlining_edge = 1;
4109 if (new_edges)
4111 new_edges->safe_push (new_direct_edge);
4112 res = true;
4114 /* If speculative edge was introduced we still need to update
4115 call info of the indirect edge. */
4116 if (!new_direct_edge->speculative)
4117 continue;
4119 if (jfunc->type == IPA_JF_PASS_THROUGH
4120 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
4122 if (ici->agg_contents
4123 && !ipa_get_jf_pass_through_agg_preserved (jfunc)
4124 && !ici->polymorphic)
4125 ici->param_index = -1;
4126 else
4128 ici->param_index = ipa_get_jf_pass_through_formal_id (jfunc);
4129 if (ici->polymorphic
4130 && !ipa_get_jf_pass_through_type_preserved (jfunc))
4131 ici->vptr_changed = true;
4132 ipa_set_param_used_by_indirect_call (new_root_info,
4133 ici->param_index, true);
4134 if (ici->polymorphic)
4135 ipa_set_param_used_by_polymorphic_call (new_root_info,
4136 ici->param_index, true);
4139 else if (jfunc->type == IPA_JF_ANCESTOR)
4141 if (ici->agg_contents
4142 && !ipa_get_jf_ancestor_agg_preserved (jfunc)
4143 && !ici->polymorphic)
4144 ici->param_index = -1;
4145 else
4147 ici->param_index = ipa_get_jf_ancestor_formal_id (jfunc);
4148 ici->offset += ipa_get_jf_ancestor_offset (jfunc);
4149 if (ici->polymorphic
4150 && !ipa_get_jf_ancestor_type_preserved (jfunc))
4151 ici->vptr_changed = true;
4152 ipa_set_param_used_by_indirect_call (new_root_info,
4153 ici->param_index, true);
4154 if (ici->polymorphic)
4155 ipa_set_param_used_by_polymorphic_call (new_root_info,
4156 ici->param_index, true);
4159 else
4160 /* Either we can find a destination for this edge now or never. */
4161 ici->param_index = -1;
4164 return res;
4167 /* Recursively traverse subtree of NODE (including node) made of inlined
4168 cgraph_edges when CS has been inlined and invoke
4169 update_indirect_edges_after_inlining on all nodes and
4170 update_jump_functions_after_inlining on all non-inlined edges that lead out
4171 of this subtree. Newly discovered indirect edges will be added to
4172 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were
4173 created. */
4175 static bool
4176 propagate_info_to_inlined_callees (struct cgraph_edge *cs,
4177 struct cgraph_node *node,
4178 vec<cgraph_edge *> *new_edges)
4180 struct cgraph_edge *e;
4181 bool res;
4183 res = update_indirect_edges_after_inlining (cs, node, new_edges);
4185 for (e = node->callees; e; e = e->next_callee)
4186 if (!e->inline_failed)
4187 res |= propagate_info_to_inlined_callees (cs, e->callee, new_edges);
4188 else
4189 update_jump_functions_after_inlining (cs, e);
4190 for (e = node->indirect_calls; e; e = e->next_callee)
4191 update_jump_functions_after_inlining (cs, e);
4193 return res;
4196 /* Combine two controlled uses counts as done during inlining. */
4198 static int
4199 combine_controlled_uses_counters (int c, int d)
4201 if (c == IPA_UNDESCRIBED_USE || d == IPA_UNDESCRIBED_USE)
4202 return IPA_UNDESCRIBED_USE;
4203 else
4204 return c + d - 1;
4207 /* Propagate number of controlled users from CS->caleee to the new root of the
4208 tree of inlined nodes. */
4210 static void
4211 propagate_controlled_uses (struct cgraph_edge *cs)
4213 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
4214 if (!args)
4215 return;
4216 struct cgraph_node *new_root = cs->caller->inlined_to
4217 ? cs->caller->inlined_to : cs->caller;
4218 ipa_node_params *new_root_info = ipa_node_params_sum->get (new_root);
4219 ipa_node_params *old_root_info = ipa_node_params_sum->get (cs->callee);
4220 int count, i;
4222 if (!old_root_info)
4223 return;
4225 count = MIN (ipa_get_cs_argument_count (args),
4226 ipa_get_param_count (old_root_info));
4227 for (i = 0; i < count; i++)
4229 struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
4230 struct ipa_cst_ref_desc *rdesc;
4232 if (jf->type == IPA_JF_PASS_THROUGH
4233 && !ipa_get_jf_pass_through_refdesc_decremented (jf))
4235 int src_idx, c, d;
4236 src_idx = ipa_get_jf_pass_through_formal_id (jf);
4237 c = ipa_get_controlled_uses (new_root_info, src_idx);
4238 d = ipa_get_controlled_uses (old_root_info, i);
4240 gcc_checking_assert (ipa_get_jf_pass_through_operation (jf)
4241 == NOP_EXPR || c == IPA_UNDESCRIBED_USE);
4242 c = combine_controlled_uses_counters (c, d);
4243 ipa_set_controlled_uses (new_root_info, src_idx, c);
4244 bool lderef = true;
4245 if (c != IPA_UNDESCRIBED_USE)
4247 lderef = (ipa_get_param_load_dereferenced (new_root_info, src_idx)
4248 || ipa_get_param_load_dereferenced (old_root_info, i));
4249 ipa_set_param_load_dereferenced (new_root_info, src_idx, lderef);
4252 if (c == 0 && !lderef && new_root_info->ipcp_orig_node)
4254 struct cgraph_node *n;
4255 struct ipa_ref *ref;
4256 tree t = new_root_info->known_csts[src_idx];
4258 if (t && TREE_CODE (t) == ADDR_EXPR
4259 && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
4260 && (n = cgraph_node::get (TREE_OPERAND (t, 0)))
4261 && (ref = new_root->find_reference (n, NULL, 0,
4262 IPA_REF_ADDR)))
4264 if (dump_file)
4265 fprintf (dump_file, "ipa-prop: Removing cloning-created "
4266 "reference from %s to %s.\n",
4267 new_root->dump_name (),
4268 n->dump_name ());
4269 ref->remove_reference ();
4273 else if (jf->type == IPA_JF_CONST
4274 && (rdesc = jfunc_rdesc_usable (jf)))
4276 int d = ipa_get_controlled_uses (old_root_info, i);
4277 int c = rdesc->refcount;
4278 tree cst = ipa_get_jf_constant (jf);
4279 rdesc->refcount = combine_controlled_uses_counters (c, d);
4280 if (rdesc->refcount != IPA_UNDESCRIBED_USE
4281 && ipa_get_param_load_dereferenced (old_root_info, i)
4282 && TREE_CODE (cst) == ADDR_EXPR
4283 && VAR_P (TREE_OPERAND (cst, 0)))
4285 symtab_node *n = symtab_node::get (TREE_OPERAND (cst, 0));
4286 new_root->create_reference (n, IPA_REF_LOAD, NULL);
4287 if (dump_file)
4288 fprintf (dump_file, "ipa-prop: Address IPA constant will reach "
4289 "a load so adding LOAD reference from %s to %s.\n",
4290 new_root->dump_name (), n->dump_name ());
4292 if (rdesc->refcount == 0)
4294 gcc_checking_assert (TREE_CODE (cst) == ADDR_EXPR
4295 && ((TREE_CODE (TREE_OPERAND (cst, 0))
4296 == FUNCTION_DECL)
4297 || VAR_P (TREE_OPERAND (cst, 0))));
4299 symtab_node *n = symtab_node::get (TREE_OPERAND (cst, 0));
4300 if (n)
4302 remove_described_reference (n, rdesc);
4303 cgraph_node *clone = cs->caller;
4304 while (clone->inlined_to
4305 && clone->ipcp_clone
4306 && clone != rdesc->cs->caller)
4308 struct ipa_ref *ref;
4309 ref = clone->find_reference (n, NULL, 0, IPA_REF_ADDR);
4310 if (ref)
4312 if (dump_file)
4313 fprintf (dump_file, "ipa-prop: Removing "
4314 "cloning-created reference "
4315 "from %s to %s.\n",
4316 clone->dump_name (),
4317 n->dump_name ());
4318 ref->remove_reference ();
4320 clone = clone->callers->caller;
4327 for (i = ipa_get_param_count (old_root_info);
4328 i < ipa_get_cs_argument_count (args);
4329 i++)
4331 struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
4333 if (jf->type == IPA_JF_CONST)
4335 struct ipa_cst_ref_desc *rdesc = jfunc_rdesc_usable (jf);
4336 if (rdesc)
4337 rdesc->refcount = IPA_UNDESCRIBED_USE;
4339 else if (jf->type == IPA_JF_PASS_THROUGH)
4340 ipa_set_controlled_uses (new_root_info,
4341 jf->value.pass_through.formal_id,
4342 IPA_UNDESCRIBED_USE);
4346 /* Update jump functions and call note functions on inlining the call site CS.
4347 CS is expected to lead to a node already cloned by
4348 cgraph_clone_inline_nodes. Newly discovered indirect edges will be added to
4349 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were +
4350 created. */
4352 bool
4353 ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
4354 vec<cgraph_edge *> *new_edges)
4356 bool changed;
4357 /* Do nothing if the preparation phase has not been carried out yet
4358 (i.e. during early inlining). */
4359 if (!ipa_node_params_sum)
4360 return false;
4361 gcc_assert (ipa_edge_args_sum);
4363 propagate_controlled_uses (cs);
4364 changed = propagate_info_to_inlined_callees (cs, cs->callee, new_edges);
4365 ipa_node_params_sum->remove (cs->callee);
4367 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
4368 if (args)
4370 bool ok = true;
4371 if (args->jump_functions)
4373 struct ipa_jump_func *jf;
4374 int i;
4375 FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
4376 if (jf->type == IPA_JF_CONST
4377 && ipa_get_jf_constant_rdesc (jf))
4379 ok = false;
4380 break;
4383 if (ok)
4384 ipa_edge_args_sum->remove (cs);
4386 if (ipcp_transformation_sum)
4387 ipcp_transformation_sum->remove (cs->callee);
4389 return changed;
4392 /* Ensure that array of edge arguments infos is big enough to accommodate a
4393 structure for all edges and reallocates it if not. Also, allocate
4394 associated hash tables is they do not already exist. */
4396 void
4397 ipa_check_create_edge_args (void)
4399 if (!ipa_edge_args_sum)
4400 ipa_edge_args_sum
4401 = (new (ggc_alloc_no_dtor<ipa_edge_args_sum_t> ())
4402 ipa_edge_args_sum_t (symtab, true));
4403 if (!ipa_bits_hash_table)
4404 ipa_bits_hash_table = hash_table<ipa_bit_ggc_hash_traits>::create_ggc (37);
4405 if (!ipa_vr_hash_table)
4406 ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
4409 /* Free all ipa_edge structures. */
4411 void
4412 ipa_free_all_edge_args (void)
4414 if (!ipa_edge_args_sum)
4415 return;
4417 ggc_delete (ipa_edge_args_sum);
4418 ipa_edge_args_sum = NULL;
4421 /* Free all ipa_node_params structures. */
4423 void
4424 ipa_free_all_node_params (void)
4426 if (ipa_node_params_sum)
4427 ggc_delete (ipa_node_params_sum);
4428 ipa_node_params_sum = NULL;
4431 /* Initialize IPA CP transformation summary and also allocate any necessary hash
4432 tables if they do not already exist. */
4434 void
4435 ipcp_transformation_initialize (void)
4437 if (!ipa_bits_hash_table)
4438 ipa_bits_hash_table = hash_table<ipa_bit_ggc_hash_traits>::create_ggc (37);
4439 if (!ipa_vr_hash_table)
4440 ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
4441 if (ipcp_transformation_sum == NULL)
4443 ipcp_transformation_sum = ipcp_transformation_t::create_ggc (symtab);
4444 ipcp_transformation_sum->disable_insertion_hook ();
4448 /* Release the IPA CP transformation summary. */
4450 void
4451 ipcp_free_transformation_sum (void)
4453 if (!ipcp_transformation_sum)
4454 return;
4456 ipcp_transformation_sum->~function_summary<ipcp_transformation *> ();
4457 ggc_free (ipcp_transformation_sum);
4458 ipcp_transformation_sum = NULL;
4461 /* Set the aggregate replacements of NODE to be AGGVALS. */
4463 void
4464 ipa_set_node_agg_value_chain (struct cgraph_node *node,
4465 vec<ipa_argagg_value, va_gc> *aggs)
4467 ipcp_transformation_initialize ();
4468 ipcp_transformation *s = ipcp_transformation_sum->get_create (node);
4469 s->m_agg_values = aggs;
4472 /* Hook that is called by cgraph.cc when an edge is removed. Adjust reference
4473 count data structures accordingly. */
4475 void
4476 ipa_edge_args_sum_t::remove (cgraph_edge *cs, ipa_edge_args *args)
4478 if (args->jump_functions)
4480 struct ipa_jump_func *jf;
4481 int i;
4482 FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
4484 struct ipa_cst_ref_desc *rdesc;
4485 try_decrement_rdesc_refcount (jf);
4486 if (jf->type == IPA_JF_CONST
4487 && (rdesc = ipa_get_jf_constant_rdesc (jf))
4488 && rdesc->cs == cs)
4489 rdesc->cs = NULL;
4494 /* Method invoked when an edge is duplicated. Copy ipa_edge_args and adjust
4495 reference count data strucutres accordingly. */
4497 void
4498 ipa_edge_args_sum_t::duplicate (cgraph_edge *src, cgraph_edge *dst,
4499 ipa_edge_args *old_args, ipa_edge_args *new_args)
4501 unsigned int i;
4503 new_args->jump_functions = vec_safe_copy (old_args->jump_functions);
4504 if (old_args->polymorphic_call_contexts)
4505 new_args->polymorphic_call_contexts
4506 = vec_safe_copy (old_args->polymorphic_call_contexts);
4508 for (i = 0; i < vec_safe_length (old_args->jump_functions); i++)
4510 struct ipa_jump_func *src_jf = ipa_get_ith_jump_func (old_args, i);
4511 struct ipa_jump_func *dst_jf = ipa_get_ith_jump_func (new_args, i);
4513 dst_jf->agg.items = vec_safe_copy (dst_jf->agg.items);
4515 if (src_jf->type == IPA_JF_CONST)
4517 struct ipa_cst_ref_desc *src_rdesc = jfunc_rdesc_usable (src_jf);
4519 if (!src_rdesc)
4520 dst_jf->value.constant.rdesc = NULL;
4521 else if (src->caller == dst->caller)
4523 /* Creation of a speculative edge. If the source edge is the one
4524 grabbing a reference, we must create a new (duplicate)
4525 reference description. Otherwise they refer to the same
4526 description corresponding to a reference taken in a function
4527 src->caller is inlined to. In that case we just must
4528 increment the refcount. */
4529 if (src_rdesc->cs == src)
4531 symtab_node *n = symtab_node_for_jfunc (src_jf);
4532 gcc_checking_assert (n);
4533 ipa_ref *ref
4534 = src->caller->find_reference (n, src->call_stmt,
4535 src->lto_stmt_uid,
4536 IPA_REF_ADDR);
4537 gcc_checking_assert (ref);
4538 dst->caller->clone_reference (ref, ref->stmt);
4540 ipa_cst_ref_desc *dst_rdesc = ipa_refdesc_pool.allocate ();
4541 dst_rdesc->cs = dst;
4542 dst_rdesc->refcount = src_rdesc->refcount;
4543 dst_rdesc->next_duplicate = NULL;
4544 dst_jf->value.constant.rdesc = dst_rdesc;
4546 else
4548 src_rdesc->refcount++;
4549 dst_jf->value.constant.rdesc = src_rdesc;
4552 else if (src_rdesc->cs == src)
4554 struct ipa_cst_ref_desc *dst_rdesc = ipa_refdesc_pool.allocate ();
4555 dst_rdesc->cs = dst;
4556 dst_rdesc->refcount = src_rdesc->refcount;
4557 dst_rdesc->next_duplicate = src_rdesc->next_duplicate;
4558 src_rdesc->next_duplicate = dst_rdesc;
4559 dst_jf->value.constant.rdesc = dst_rdesc;
4561 else
4563 struct ipa_cst_ref_desc *dst_rdesc;
4564 /* This can happen during inlining, when a JFUNC can refer to a
4565 reference taken in a function up in the tree of inline clones.
4566 We need to find the duplicate that refers to our tree of
4567 inline clones. */
4569 gcc_assert (dst->caller->inlined_to);
4570 for (dst_rdesc = src_rdesc->next_duplicate;
4571 dst_rdesc;
4572 dst_rdesc = dst_rdesc->next_duplicate)
4574 struct cgraph_node *top;
4575 top = dst_rdesc->cs->caller->inlined_to
4576 ? dst_rdesc->cs->caller->inlined_to
4577 : dst_rdesc->cs->caller;
4578 if (dst->caller->inlined_to == top)
4579 break;
4581 gcc_assert (dst_rdesc);
4582 dst_jf->value.constant.rdesc = dst_rdesc;
4585 else if (dst_jf->type == IPA_JF_PASS_THROUGH
4586 && src->caller == dst->caller)
4588 struct cgraph_node *inline_root = dst->caller->inlined_to
4589 ? dst->caller->inlined_to : dst->caller;
4590 ipa_node_params *root_info = ipa_node_params_sum->get (inline_root);
4591 int idx = ipa_get_jf_pass_through_formal_id (dst_jf);
4593 int c = ipa_get_controlled_uses (root_info, idx);
4594 if (c != IPA_UNDESCRIBED_USE)
4596 c++;
4597 ipa_set_controlled_uses (root_info, idx, c);
4603 /* Analyze newly added function into callgraph. */
4605 static void
4606 ipa_add_new_function (cgraph_node *node, void *data ATTRIBUTE_UNUSED)
4608 if (node->has_gimple_body_p ())
4609 ipa_analyze_node (node);
4612 /* Hook that is called by summary when a node is duplicated. */
4614 void
4615 ipa_node_params_t::duplicate(cgraph_node *, cgraph_node *,
4616 ipa_node_params *old_info,
4617 ipa_node_params *new_info)
4619 new_info->descriptors = vec_safe_copy (old_info->descriptors);
4620 new_info->lattices = NULL;
4621 new_info->ipcp_orig_node = old_info->ipcp_orig_node;
4622 new_info->known_csts = old_info->known_csts.copy ();
4623 new_info->known_contexts = old_info->known_contexts.copy ();
4625 new_info->analysis_done = old_info->analysis_done;
4626 new_info->node_enqueued = old_info->node_enqueued;
4627 new_info->versionable = old_info->versionable;
4630 /* Duplication of ipcp transformation summaries. */
4632 void
4633 ipcp_transformation_t::duplicate(cgraph_node *, cgraph_node *dst,
4634 ipcp_transformation *src_trans,
4635 ipcp_transformation *dst_trans)
4637 /* Avoid redundant work of duplicating vectors we will never use. */
4638 if (dst->inlined_to)
4639 return;
4640 dst_trans->m_agg_values = vec_safe_copy (src_trans->m_agg_values);
4641 dst_trans->bits = vec_safe_copy (src_trans->bits);
4642 dst_trans->m_vr = vec_safe_copy (src_trans->m_vr);
4645 /* Register our cgraph hooks if they are not already there. */
4647 void
4648 ipa_register_cgraph_hooks (void)
4650 ipa_check_create_node_params ();
4651 ipa_check_create_edge_args ();
4653 function_insertion_hook_holder =
4654 symtab->add_cgraph_insertion_hook (&ipa_add_new_function, NULL);
4657 /* Unregister our cgraph hooks if they are not already there. */
4659 static void
4660 ipa_unregister_cgraph_hooks (void)
4662 if (function_insertion_hook_holder)
4663 symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
4664 function_insertion_hook_holder = NULL;
4667 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
4668 longer needed after ipa-cp. */
4670 void
4671 ipa_free_all_structures_after_ipa_cp (void)
4673 if (!optimize && !in_lto_p)
4675 ipa_free_all_edge_args ();
4676 ipa_free_all_node_params ();
4677 ipcp_sources_pool.release ();
4678 ipcp_cst_values_pool.release ();
4679 ipcp_poly_ctx_values_pool.release ();
4680 ipcp_agg_lattice_pool.release ();
4681 ipa_unregister_cgraph_hooks ();
4682 ipa_refdesc_pool.release ();
4686 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
4687 longer needed after indirect inlining. */
4689 void
4690 ipa_free_all_structures_after_iinln (void)
4692 ipa_free_all_edge_args ();
4693 ipa_free_all_node_params ();
4694 ipa_unregister_cgraph_hooks ();
4695 ipcp_sources_pool.release ();
4696 ipcp_cst_values_pool.release ();
4697 ipcp_poly_ctx_values_pool.release ();
4698 ipcp_agg_lattice_pool.release ();
4699 ipa_refdesc_pool.release ();
4702 /* Print ipa_tree_map data structures of all functions in the
4703 callgraph to F. */
4705 void
4706 ipa_print_node_params (FILE *f, struct cgraph_node *node)
4708 int i, count;
4709 class ipa_node_params *info;
4711 if (!node->definition)
4712 return;
4713 info = ipa_node_params_sum->get (node);
4714 fprintf (f, " function %s parameter descriptors:\n", node->dump_name ());
4715 if (!info)
4717 fprintf (f, " no params return\n");
4718 return;
4720 count = ipa_get_param_count (info);
4721 for (i = 0; i < count; i++)
4723 int c;
4725 fprintf (f, " ");
4726 ipa_dump_param (f, info, i);
4727 if (ipa_is_param_used (info, i))
4728 fprintf (f, " used");
4729 if (ipa_is_param_used_by_ipa_predicates (info, i))
4730 fprintf (f, " used_by_ipa_predicates");
4731 if (ipa_is_param_used_by_indirect_call (info, i))
4732 fprintf (f, " used_by_indirect_call");
4733 if (ipa_is_param_used_by_polymorphic_call (info, i))
4734 fprintf (f, " used_by_polymorphic_call");
4735 c = ipa_get_controlled_uses (info, i);
4736 if (c == IPA_UNDESCRIBED_USE)
4737 fprintf (f, " undescribed_use");
4738 else
4739 fprintf (f, " controlled_uses=%i %s", c,
4740 ipa_get_param_load_dereferenced (info, i)
4741 ? "(load_dereferenced)" : "");
4742 fprintf (f, "\n");
4746 /* Print ipa_tree_map data structures of all functions in the
4747 callgraph to F. */
4749 void
4750 ipa_print_all_params (FILE * f)
4752 struct cgraph_node *node;
4754 fprintf (f, "\nFunction parameters:\n");
4755 FOR_EACH_FUNCTION (node)
4756 ipa_print_node_params (f, node);
4759 /* Stream out jump function JUMP_FUNC to OB. */
4761 static void
4762 ipa_write_jump_function (struct output_block *ob,
4763 struct ipa_jump_func *jump_func)
4765 struct ipa_agg_jf_item *item;
4766 struct bitpack_d bp;
4767 int i, count;
4768 int flag = 0;
4770 /* ADDR_EXPRs are very comon IP invariants; save some streamer data
4771 as well as WPA memory by handling them specially. */
4772 if (jump_func->type == IPA_JF_CONST
4773 && TREE_CODE (jump_func->value.constant.value) == ADDR_EXPR)
4774 flag = 1;
4776 streamer_write_uhwi (ob, jump_func->type * 2 + flag);
4777 switch (jump_func->type)
4779 case IPA_JF_UNKNOWN:
4780 break;
4781 case IPA_JF_CONST:
4782 gcc_assert (
4783 EXPR_LOCATION (jump_func->value.constant.value) == UNKNOWN_LOCATION);
4784 stream_write_tree (ob,
4785 flag
4786 ? TREE_OPERAND (jump_func->value.constant.value, 0)
4787 : jump_func->value.constant.value, true);
4788 break;
4789 case IPA_JF_PASS_THROUGH:
4790 streamer_write_uhwi (ob, jump_func->value.pass_through.operation);
4791 if (jump_func->value.pass_through.operation == NOP_EXPR)
4793 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4794 bp = bitpack_create (ob->main_stream);
4795 bp_pack_value (&bp, jump_func->value.pass_through.agg_preserved, 1);
4796 gcc_assert (!jump_func->value.pass_through.refdesc_decremented);
4797 streamer_write_bitpack (&bp);
4799 else if (TREE_CODE_CLASS (jump_func->value.pass_through.operation)
4800 == tcc_unary)
4801 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4802 else
4804 stream_write_tree (ob, jump_func->value.pass_through.operand, true);
4805 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4807 break;
4808 case IPA_JF_ANCESTOR:
4809 streamer_write_uhwi (ob, jump_func->value.ancestor.offset);
4810 streamer_write_uhwi (ob, jump_func->value.ancestor.formal_id);
4811 bp = bitpack_create (ob->main_stream);
4812 bp_pack_value (&bp, jump_func->value.ancestor.agg_preserved, 1);
4813 bp_pack_value (&bp, jump_func->value.ancestor.keep_null, 1);
4814 streamer_write_bitpack (&bp);
4815 break;
4816 default:
4817 fatal_error (UNKNOWN_LOCATION, "invalid jump function in LTO stream");
4820 count = vec_safe_length (jump_func->agg.items);
4821 streamer_write_uhwi (ob, count);
4822 if (count)
4824 bp = bitpack_create (ob->main_stream);
4825 bp_pack_value (&bp, jump_func->agg.by_ref, 1);
4826 streamer_write_bitpack (&bp);
4829 FOR_EACH_VEC_SAFE_ELT (jump_func->agg.items, i, item)
4831 stream_write_tree (ob, item->type, true);
4832 streamer_write_uhwi (ob, item->offset);
4833 streamer_write_uhwi (ob, item->jftype);
4834 switch (item->jftype)
4836 case IPA_JF_UNKNOWN:
4837 break;
4838 case IPA_JF_CONST:
4839 stream_write_tree (ob, item->value.constant, true);
4840 break;
4841 case IPA_JF_PASS_THROUGH:
4842 case IPA_JF_LOAD_AGG:
4843 streamer_write_uhwi (ob, item->value.pass_through.operation);
4844 streamer_write_uhwi (ob, item->value.pass_through.formal_id);
4845 if (TREE_CODE_CLASS (item->value.pass_through.operation)
4846 != tcc_unary)
4847 stream_write_tree (ob, item->value.pass_through.operand, true);
4848 if (item->jftype == IPA_JF_LOAD_AGG)
4850 stream_write_tree (ob, item->value.load_agg.type, true);
4851 streamer_write_uhwi (ob, item->value.load_agg.offset);
4852 bp = bitpack_create (ob->main_stream);
4853 bp_pack_value (&bp, item->value.load_agg.by_ref, 1);
4854 streamer_write_bitpack (&bp);
4856 break;
4857 default:
4858 fatal_error (UNKNOWN_LOCATION,
4859 "invalid jump function in LTO stream");
4863 bp = bitpack_create (ob->main_stream);
4864 bp_pack_value (&bp, !!jump_func->bits, 1);
4865 streamer_write_bitpack (&bp);
4866 if (jump_func->bits)
4868 streamer_write_widest_int (ob, jump_func->bits->value);
4869 streamer_write_widest_int (ob, jump_func->bits->mask);
4871 if (jump_func->m_vr)
4872 jump_func->m_vr->streamer_write (ob);
4873 else
4875 bp_pack_value (&bp, false, 1);
4876 streamer_write_bitpack (&bp);
4880 /* Read in jump function JUMP_FUNC from IB. */
4882 static void
4883 ipa_read_jump_function (class lto_input_block *ib,
4884 struct ipa_jump_func *jump_func,
4885 struct cgraph_edge *cs,
4886 class data_in *data_in,
4887 bool prevails)
4889 enum jump_func_type jftype;
4890 enum tree_code operation;
4891 int i, count;
4892 int val = streamer_read_uhwi (ib);
4893 bool flag = val & 1;
4895 jftype = (enum jump_func_type) (val / 2);
4896 switch (jftype)
4898 case IPA_JF_UNKNOWN:
4899 ipa_set_jf_unknown (jump_func);
4900 break;
4901 case IPA_JF_CONST:
4903 tree t = stream_read_tree (ib, data_in);
4904 if (flag && prevails)
4905 t = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
4906 ipa_set_jf_constant (jump_func, t, cs);
4908 break;
4909 case IPA_JF_PASS_THROUGH:
4910 operation = (enum tree_code) streamer_read_uhwi (ib);
4911 if (operation == NOP_EXPR)
4913 int formal_id = streamer_read_uhwi (ib);
4914 struct bitpack_d bp = streamer_read_bitpack (ib);
4915 bool agg_preserved = bp_unpack_value (&bp, 1);
4916 ipa_set_jf_simple_pass_through (jump_func, formal_id, agg_preserved);
4918 else if (TREE_CODE_CLASS (operation) == tcc_unary)
4920 int formal_id = streamer_read_uhwi (ib);
4921 ipa_set_jf_unary_pass_through (jump_func, formal_id, operation);
4923 else
4925 tree operand = stream_read_tree (ib, data_in);
4926 int formal_id = streamer_read_uhwi (ib);
4927 ipa_set_jf_arith_pass_through (jump_func, formal_id, operand,
4928 operation);
4930 break;
4931 case IPA_JF_ANCESTOR:
4933 HOST_WIDE_INT offset = streamer_read_uhwi (ib);
4934 int formal_id = streamer_read_uhwi (ib);
4935 struct bitpack_d bp = streamer_read_bitpack (ib);
4936 bool agg_preserved = bp_unpack_value (&bp, 1);
4937 bool keep_null = bp_unpack_value (&bp, 1);
4938 ipa_set_ancestor_jf (jump_func, offset, formal_id, agg_preserved,
4939 keep_null);
4940 break;
4942 default:
4943 fatal_error (UNKNOWN_LOCATION, "invalid jump function in LTO stream");
4946 count = streamer_read_uhwi (ib);
4947 if (prevails)
4949 jump_func->agg.items = NULL;
4950 vec_safe_reserve (jump_func->agg.items, count, true);
4952 if (count)
4954 struct bitpack_d bp = streamer_read_bitpack (ib);
4955 jump_func->agg.by_ref = bp_unpack_value (&bp, 1);
4957 for (i = 0; i < count; i++)
4959 struct ipa_agg_jf_item item;
4960 item.type = stream_read_tree (ib, data_in);
4961 item.offset = streamer_read_uhwi (ib);
4962 item.jftype = (enum jump_func_type) streamer_read_uhwi (ib);
4964 switch (item.jftype)
4966 case IPA_JF_UNKNOWN:
4967 break;
4968 case IPA_JF_CONST:
4969 item.value.constant = stream_read_tree (ib, data_in);
4970 break;
4971 case IPA_JF_PASS_THROUGH:
4972 case IPA_JF_LOAD_AGG:
4973 operation = (enum tree_code) streamer_read_uhwi (ib);
4974 item.value.pass_through.operation = operation;
4975 item.value.pass_through.formal_id = streamer_read_uhwi (ib);
4976 if (TREE_CODE_CLASS (operation) == tcc_unary)
4977 item.value.pass_through.operand = NULL_TREE;
4978 else
4979 item.value.pass_through.operand = stream_read_tree (ib, data_in);
4980 if (item.jftype == IPA_JF_LOAD_AGG)
4982 struct bitpack_d bp;
4983 item.value.load_agg.type = stream_read_tree (ib, data_in);
4984 item.value.load_agg.offset = streamer_read_uhwi (ib);
4985 bp = streamer_read_bitpack (ib);
4986 item.value.load_agg.by_ref = bp_unpack_value (&bp, 1);
4988 break;
4989 default:
4990 fatal_error (UNKNOWN_LOCATION,
4991 "invalid jump function in LTO stream");
4993 if (prevails)
4994 jump_func->agg.items->quick_push (item);
4997 struct bitpack_d bp = streamer_read_bitpack (ib);
4998 bool bits_known = bp_unpack_value (&bp, 1);
4999 if (bits_known)
5001 widest_int value = streamer_read_widest_int (ib);
5002 widest_int mask = streamer_read_widest_int (ib);
5003 if (prevails)
5004 ipa_set_jfunc_bits (jump_func, value, mask);
5006 else
5007 jump_func->bits = NULL;
5009 ipa_vr vr;
5010 vr.streamer_read (ib, data_in);
5011 if (vr.known_p ())
5013 if (prevails)
5014 ipa_set_jfunc_vr (jump_func, vr);
5016 else
5017 jump_func->m_vr = NULL;
5020 /* Stream out parts of cgraph_indirect_call_info corresponding to CS that are
5021 relevant to indirect inlining to OB. */
5023 static void
5024 ipa_write_indirect_edge_info (struct output_block *ob,
5025 struct cgraph_edge *cs)
5027 class cgraph_indirect_call_info *ii = cs->indirect_info;
5028 struct bitpack_d bp;
5030 streamer_write_hwi (ob, ii->param_index);
5031 bp = bitpack_create (ob->main_stream);
5032 bp_pack_value (&bp, ii->polymorphic, 1);
5033 bp_pack_value (&bp, ii->agg_contents, 1);
5034 bp_pack_value (&bp, ii->member_ptr, 1);
5035 bp_pack_value (&bp, ii->by_ref, 1);
5036 bp_pack_value (&bp, ii->guaranteed_unmodified, 1);
5037 bp_pack_value (&bp, ii->vptr_changed, 1);
5038 streamer_write_bitpack (&bp);
5039 if (ii->agg_contents || ii->polymorphic)
5040 streamer_write_hwi (ob, ii->offset);
5041 else
5042 gcc_assert (ii->offset == 0);
5044 if (ii->polymorphic)
5046 streamer_write_hwi (ob, ii->otr_token);
5047 stream_write_tree (ob, ii->otr_type, true);
5048 ii->context.stream_out (ob);
5052 /* Read in parts of cgraph_indirect_call_info corresponding to CS that are
5053 relevant to indirect inlining from IB. */
5055 static void
5056 ipa_read_indirect_edge_info (class lto_input_block *ib,
5057 class data_in *data_in,
5058 struct cgraph_edge *cs,
5059 class ipa_node_params *info)
5061 class cgraph_indirect_call_info *ii = cs->indirect_info;
5062 struct bitpack_d bp;
5064 ii->param_index = (int) streamer_read_hwi (ib);
5065 bp = streamer_read_bitpack (ib);
5066 ii->polymorphic = bp_unpack_value (&bp, 1);
5067 ii->agg_contents = bp_unpack_value (&bp, 1);
5068 ii->member_ptr = bp_unpack_value (&bp, 1);
5069 ii->by_ref = bp_unpack_value (&bp, 1);
5070 ii->guaranteed_unmodified = bp_unpack_value (&bp, 1);
5071 ii->vptr_changed = bp_unpack_value (&bp, 1);
5072 if (ii->agg_contents || ii->polymorphic)
5073 ii->offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
5074 else
5075 ii->offset = 0;
5076 if (ii->polymorphic)
5078 ii->otr_token = (HOST_WIDE_INT) streamer_read_hwi (ib);
5079 ii->otr_type = stream_read_tree (ib, data_in);
5080 ii->context.stream_in (ib, data_in);
5082 if (info && ii->param_index >= 0)
5084 if (ii->polymorphic)
5085 ipa_set_param_used_by_polymorphic_call (info,
5086 ii->param_index , true);
5087 ipa_set_param_used_by_indirect_call (info,
5088 ii->param_index, true);
5092 /* Stream out NODE info to OB. */
5094 static void
5095 ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
5097 int node_ref;
5098 lto_symtab_encoder_t encoder;
5099 ipa_node_params *info = ipa_node_params_sum->get (node);
5100 int j;
5101 struct cgraph_edge *e;
5102 struct bitpack_d bp;
5104 encoder = ob->decl_state->symtab_node_encoder;
5105 node_ref = lto_symtab_encoder_encode (encoder, node);
5106 streamer_write_uhwi (ob, node_ref);
5108 streamer_write_uhwi (ob, ipa_get_param_count (info));
5109 for (j = 0; j < ipa_get_param_count (info); j++)
5110 streamer_write_uhwi (ob, ipa_get_param_move_cost (info, j));
5111 bp = bitpack_create (ob->main_stream);
5112 gcc_assert (info->analysis_done
5113 || ipa_get_param_count (info) == 0);
5114 gcc_assert (!info->node_enqueued);
5115 gcc_assert (!info->ipcp_orig_node);
5116 for (j = 0; j < ipa_get_param_count (info); j++)
5118 /* TODO: We could just not stream the bit in the undescribed case. */
5119 bool d = (ipa_get_controlled_uses (info, j) != IPA_UNDESCRIBED_USE)
5120 ? ipa_get_param_load_dereferenced (info, j) : true;
5121 bp_pack_value (&bp, d, 1);
5122 bp_pack_value (&bp, ipa_is_param_used (info, j), 1);
5124 streamer_write_bitpack (&bp);
5125 for (j = 0; j < ipa_get_param_count (info); j++)
5127 streamer_write_hwi (ob, ipa_get_controlled_uses (info, j));
5128 stream_write_tree (ob, ipa_get_type (info, j), true);
5130 for (e = node->callees; e; e = e->next_callee)
5132 ipa_edge_args *args = ipa_edge_args_sum->get (e);
5134 if (!args)
5136 streamer_write_uhwi (ob, 0);
5137 continue;
5140 streamer_write_uhwi (ob,
5141 ipa_get_cs_argument_count (args) * 2
5142 + (args->polymorphic_call_contexts != NULL));
5143 for (j = 0; j < ipa_get_cs_argument_count (args); j++)
5145 ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
5146 if (args->polymorphic_call_contexts != NULL)
5147 ipa_get_ith_polymorhic_call_context (args, j)->stream_out (ob);
5150 for (e = node->indirect_calls; e; e = e->next_callee)
5152 ipa_edge_args *args = ipa_edge_args_sum->get (e);
5153 if (!args)
5154 streamer_write_uhwi (ob, 0);
5155 else
5157 streamer_write_uhwi (ob,
5158 ipa_get_cs_argument_count (args) * 2
5159 + (args->polymorphic_call_contexts != NULL));
5160 for (j = 0; j < ipa_get_cs_argument_count (args); j++)
5162 ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
5163 if (args->polymorphic_call_contexts != NULL)
5164 ipa_get_ith_polymorhic_call_context (args, j)->stream_out (ob);
5167 ipa_write_indirect_edge_info (ob, e);
5171 /* Stream in edge E from IB. */
5173 static void
5174 ipa_read_edge_info (class lto_input_block *ib,
5175 class data_in *data_in,
5176 struct cgraph_edge *e, bool prevails)
5178 int count = streamer_read_uhwi (ib);
5179 bool contexts_computed = count & 1;
5181 count /= 2;
5182 if (!count)
5183 return;
5184 if (prevails
5185 && (e->possibly_call_in_translation_unit_p ()
5186 /* Also stream in jump functions to builtins in hope that they
5187 will get fnspecs. */
5188 || fndecl_built_in_p (e->callee->decl, BUILT_IN_NORMAL)))
5190 ipa_edge_args *args = ipa_edge_args_sum->get_create (e);
5191 vec_safe_grow_cleared (args->jump_functions, count, true);
5192 if (contexts_computed)
5193 vec_safe_grow_cleared (args->polymorphic_call_contexts, count, true);
5194 for (int k = 0; k < count; k++)
5196 ipa_read_jump_function (ib, ipa_get_ith_jump_func (args, k), e,
5197 data_in, prevails);
5198 if (contexts_computed)
5199 ipa_get_ith_polymorhic_call_context (args, k)->stream_in
5200 (ib, data_in);
5203 else
5205 for (int k = 0; k < count; k++)
5207 struct ipa_jump_func dummy;
5208 ipa_read_jump_function (ib, &dummy, e,
5209 data_in, prevails);
5210 if (contexts_computed)
5212 class ipa_polymorphic_call_context ctx;
5213 ctx.stream_in (ib, data_in);
5219 /* Stream in NODE info from IB. */
5221 static void
5222 ipa_read_node_info (class lto_input_block *ib, struct cgraph_node *node,
5223 class data_in *data_in)
5225 int k;
5226 struct cgraph_edge *e;
5227 struct bitpack_d bp;
5228 bool prevails = node->prevailing_p ();
5229 ipa_node_params *info
5230 = prevails ? ipa_node_params_sum->get_create (node) : NULL;
5232 int param_count = streamer_read_uhwi (ib);
5233 if (prevails)
5235 ipa_alloc_node_params (node, param_count);
5236 for (k = 0; k < param_count; k++)
5237 (*info->descriptors)[k].move_cost = streamer_read_uhwi (ib);
5238 if (ipa_get_param_count (info) != 0)
5239 info->analysis_done = true;
5240 info->node_enqueued = false;
5242 else
5243 for (k = 0; k < param_count; k++)
5244 streamer_read_uhwi (ib);
5246 bp = streamer_read_bitpack (ib);
5247 for (k = 0; k < param_count; k++)
5249 bool load_dereferenced = bp_unpack_value (&bp, 1);
5250 bool used = bp_unpack_value (&bp, 1);
5252 if (prevails)
5254 ipa_set_param_load_dereferenced (info, k, load_dereferenced);
5255 ipa_set_param_used (info, k, used);
5258 for (k = 0; k < param_count; k++)
5260 int nuses = streamer_read_hwi (ib);
5261 tree type = stream_read_tree (ib, data_in);
5263 if (prevails)
5265 ipa_set_controlled_uses (info, k, nuses);
5266 (*info->descriptors)[k].decl_or_type = type;
5269 for (e = node->callees; e; e = e->next_callee)
5270 ipa_read_edge_info (ib, data_in, e, prevails);
5271 for (e = node->indirect_calls; e; e = e->next_callee)
5273 ipa_read_edge_info (ib, data_in, e, prevails);
5274 ipa_read_indirect_edge_info (ib, data_in, e, info);
5278 /* Write jump functions for nodes in SET. */
5280 void
5281 ipa_prop_write_jump_functions (void)
5283 struct output_block *ob;
5284 unsigned int count = 0;
5285 lto_symtab_encoder_iterator lsei;
5286 lto_symtab_encoder_t encoder;
5288 if (!ipa_node_params_sum || !ipa_edge_args_sum)
5289 return;
5291 ob = create_output_block (LTO_section_jump_functions);
5292 encoder = ob->decl_state->symtab_node_encoder;
5293 ob->symbol = NULL;
5294 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
5295 lsei_next_function_in_partition (&lsei))
5297 cgraph_node *node = lsei_cgraph_node (lsei);
5298 if (node->has_gimple_body_p ()
5299 && ipa_node_params_sum->get (node) != NULL)
5300 count++;
5303 streamer_write_uhwi (ob, count);
5305 /* Process all of the functions. */
5306 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
5307 lsei_next_function_in_partition (&lsei))
5309 cgraph_node *node = lsei_cgraph_node (lsei);
5310 if (node->has_gimple_body_p ()
5311 && ipa_node_params_sum->get (node) != NULL)
5312 ipa_write_node_info (ob, node);
5314 streamer_write_char_stream (ob->main_stream, 0);
5315 produce_asm (ob, NULL);
5316 destroy_output_block (ob);
5319 /* Read section in file FILE_DATA of length LEN with data DATA. */
5321 static void
5322 ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
5323 size_t len)
5325 const struct lto_function_header *header =
5326 (const struct lto_function_header *) data;
5327 const int cfg_offset = sizeof (struct lto_function_header);
5328 const int main_offset = cfg_offset + header->cfg_size;
5329 const int string_offset = main_offset + header->main_size;
5330 class data_in *data_in;
5331 unsigned int i;
5332 unsigned int count;
5334 lto_input_block ib_main ((const char *) data + main_offset,
5335 header->main_size, file_data->mode_table);
5337 data_in =
5338 lto_data_in_create (file_data, (const char *) data + string_offset,
5339 header->string_size, vNULL);
5340 count = streamer_read_uhwi (&ib_main);
5342 for (i = 0; i < count; i++)
5344 unsigned int index;
5345 struct cgraph_node *node;
5346 lto_symtab_encoder_t encoder;
5348 index = streamer_read_uhwi (&ib_main);
5349 encoder = file_data->symtab_node_encoder;
5350 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
5351 index));
5352 gcc_assert (node->definition);
5353 ipa_read_node_info (&ib_main, node, data_in);
5355 lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
5356 len);
5357 lto_data_in_delete (data_in);
5360 /* Read ipcp jump functions. */
5362 void
5363 ipa_prop_read_jump_functions (void)
5365 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
5366 struct lto_file_decl_data *file_data;
5367 unsigned int j = 0;
5369 ipa_check_create_node_params ();
5370 ipa_check_create_edge_args ();
5371 ipa_register_cgraph_hooks ();
5373 while ((file_data = file_data_vec[j++]))
5375 size_t len;
5376 const char *data
5377 = lto_get_summary_section_data (file_data, LTO_section_jump_functions,
5378 &len);
5379 if (data)
5380 ipa_prop_read_section (file_data, data, len);
5384 /* Return true if the IPA-CP transformation summary TS is non-NULL and contains
5385 useful info. */
5386 static bool
5387 useful_ipcp_transformation_info_p (ipcp_transformation *ts)
5389 if (!ts)
5390 return false;
5391 if (!vec_safe_is_empty (ts->m_agg_values)
5392 || !vec_safe_is_empty (ts->bits)
5393 || !vec_safe_is_empty (ts->m_vr))
5394 return true;
5395 return false;
5398 /* Write into OB IPA-CP transfromation summary TS describing NODE. */
5400 void
5401 write_ipcp_transformation_info (output_block *ob, cgraph_node *node,
5402 ipcp_transformation *ts)
5404 lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
5405 int node_ref = lto_symtab_encoder_encode (encoder, node);
5406 streamer_write_uhwi (ob, node_ref);
5408 streamer_write_uhwi (ob, vec_safe_length (ts->m_agg_values));
5409 for (const ipa_argagg_value &av : ts->m_agg_values)
5411 struct bitpack_d bp;
5413 stream_write_tree (ob, av.value, true);
5414 streamer_write_uhwi (ob, av.unit_offset);
5415 streamer_write_uhwi (ob, av.index);
5417 bp = bitpack_create (ob->main_stream);
5418 bp_pack_value (&bp, av.by_ref, 1);
5419 streamer_write_bitpack (&bp);
5422 streamer_write_uhwi (ob, vec_safe_length (ts->m_vr));
5423 for (const ipa_vr &parm_vr : ts->m_vr)
5424 parm_vr.streamer_write (ob);
5426 streamer_write_uhwi (ob, vec_safe_length (ts->bits));
5427 for (const ipa_bits *bits_jfunc : ts->bits)
5429 struct bitpack_d bp = bitpack_create (ob->main_stream);
5430 bp_pack_value (&bp, !!bits_jfunc, 1);
5431 streamer_write_bitpack (&bp);
5432 if (bits_jfunc)
5434 streamer_write_widest_int (ob, bits_jfunc->value);
5435 streamer_write_widest_int (ob, bits_jfunc->mask);
5440 /* Stream in the aggregate value replacement chain for NODE from IB. */
5442 static void
5443 read_ipcp_transformation_info (lto_input_block *ib, cgraph_node *node,
5444 data_in *data_in)
5446 unsigned int count, i;
5447 ipcp_transformation_initialize ();
5448 ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
5450 count = streamer_read_uhwi (ib);
5451 if (count > 0)
5453 vec_safe_grow_cleared (ts->m_agg_values, count, true);
5454 for (i = 0; i <count; i++)
5456 ipa_argagg_value *av = &(*ts->m_agg_values)[i];;
5458 av->value = stream_read_tree (ib, data_in);
5459 av->unit_offset = streamer_read_uhwi (ib);
5460 av->index = streamer_read_uhwi (ib);
5462 bitpack_d bp = streamer_read_bitpack (ib);
5463 av->by_ref = bp_unpack_value (&bp, 1);
5467 count = streamer_read_uhwi (ib);
5468 if (count > 0)
5470 vec_safe_grow_cleared (ts->m_vr, count, true);
5471 for (i = 0; i < count; i++)
5473 ipa_vr *parm_vr;
5474 parm_vr = &(*ts->m_vr)[i];
5475 parm_vr->streamer_read (ib, data_in);
5478 count = streamer_read_uhwi (ib);
5479 if (count > 0)
5481 vec_safe_grow_cleared (ts->bits, count, true);
5482 for (i = 0; i < count; i++)
5484 struct bitpack_d bp = streamer_read_bitpack (ib);
5485 bool known = bp_unpack_value (&bp, 1);
5486 if (known)
5488 const widest_int value = streamer_read_widest_int (ib);
5489 const widest_int mask = streamer_read_widest_int (ib);
5490 ipa_bits *bits
5491 = ipa_get_ipa_bits_for_value (value, mask);
5492 (*ts->bits)[i] = bits;
5498 /* Write all aggregate replacement for nodes in set. */
5500 void
5501 ipcp_write_transformation_summaries (void)
5503 struct output_block *ob;
5504 unsigned int count = 0;
5505 lto_symtab_encoder_t encoder;
5507 ob = create_output_block (LTO_section_ipcp_transform);
5508 encoder = ob->decl_state->symtab_node_encoder;
5509 ob->symbol = NULL;
5511 for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
5513 symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
5514 cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
5515 if (!cnode)
5516 continue;
5517 ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
5518 if (useful_ipcp_transformation_info_p (ts)
5519 && lto_symtab_encoder_encode_body_p (encoder, cnode))
5520 count++;
5523 streamer_write_uhwi (ob, count);
5525 for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
5527 symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
5528 cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
5529 if (!cnode)
5530 continue;
5531 ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
5532 if (useful_ipcp_transformation_info_p (ts)
5533 && lto_symtab_encoder_encode_body_p (encoder, cnode))
5534 write_ipcp_transformation_info (ob, cnode, ts);
5536 streamer_write_char_stream (ob->main_stream, 0);
5537 produce_asm (ob, NULL);
5538 destroy_output_block (ob);
5541 /* Read replacements section in file FILE_DATA of length LEN with data
5542 DATA. */
5544 static void
5545 read_replacements_section (struct lto_file_decl_data *file_data,
5546 const char *data,
5547 size_t len)
5549 const struct lto_function_header *header =
5550 (const struct lto_function_header *) data;
5551 const int cfg_offset = sizeof (struct lto_function_header);
5552 const int main_offset = cfg_offset + header->cfg_size;
5553 const int string_offset = main_offset + header->main_size;
5554 class data_in *data_in;
5555 unsigned int i;
5556 unsigned int count;
5558 lto_input_block ib_main ((const char *) data + main_offset,
5559 header->main_size, file_data->mode_table);
5561 data_in = lto_data_in_create (file_data, (const char *) data + string_offset,
5562 header->string_size, vNULL);
5563 count = streamer_read_uhwi (&ib_main);
5565 for (i = 0; i < count; i++)
5567 unsigned int index;
5568 struct cgraph_node *node;
5569 lto_symtab_encoder_t encoder;
5571 index = streamer_read_uhwi (&ib_main);
5572 encoder = file_data->symtab_node_encoder;
5573 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
5574 index));
5575 read_ipcp_transformation_info (&ib_main, node, data_in);
5577 lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
5578 len);
5579 lto_data_in_delete (data_in);
5582 /* Read IPA-CP aggregate replacements. */
5584 void
5585 ipcp_read_transformation_summaries (void)
5587 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
5588 struct lto_file_decl_data *file_data;
5589 unsigned int j = 0;
5591 while ((file_data = file_data_vec[j++]))
5593 size_t len;
5594 const char *data
5595 = lto_get_summary_section_data (file_data, LTO_section_ipcp_transform,
5596 &len);
5597 if (data)
5598 read_replacements_section (file_data, data, len);
5602 /* Adjust the aggregate replacements in TS to reflect any parameter removals
5603 which might have already taken place. If after adjustments there are no
5604 aggregate replacements left, the m_agg_values will be set to NULL. In other
5605 cases, it may be shrunk. */
5607 static void
5608 adjust_agg_replacement_values (cgraph_node *node, ipcp_transformation *ts)
5610 clone_info *cinfo = clone_info::get (node);
5611 if (!cinfo || !cinfo->param_adjustments)
5612 return;
5614 auto_vec<int, 16> new_indices;
5615 cinfo->param_adjustments->get_updated_indices (&new_indices);
5616 bool removed_item = false;
5617 unsigned dst_index = 0;
5618 unsigned count = ts->m_agg_values->length ();
5619 for (unsigned i = 0; i < count; i++)
5621 ipa_argagg_value *v = &(*ts->m_agg_values)[i];
5622 gcc_checking_assert (v->index >= 0);
5624 int new_idx = -1;
5625 if ((unsigned) v->index < new_indices.length ())
5626 new_idx = new_indices[v->index];
5628 if (new_idx >= 0)
5630 v->index = new_idx;
5631 if (removed_item)
5632 (*ts->m_agg_values)[dst_index] = *v;
5633 dst_index++;
5635 else
5636 removed_item = true;
5639 if (dst_index == 0)
5641 ggc_free (ts->m_agg_values);
5642 ts->m_agg_values = NULL;
5644 else if (removed_item)
5645 ts->m_agg_values->truncate (dst_index);
5647 return;
5650 /* Dominator walker driving the ipcp modification phase. */
5652 class ipcp_modif_dom_walker : public dom_walker
5654 public:
5655 ipcp_modif_dom_walker (struct ipa_func_body_info *fbi,
5656 vec<ipa_param_descriptor, va_gc> *descs,
5657 ipcp_transformation *ts, bool *sc)
5658 : dom_walker (CDI_DOMINATORS), m_fbi (fbi), m_descriptors (descs),
5659 m_ts (ts), m_something_changed (sc) {}
5661 edge before_dom_children (basic_block) final override;
5662 bool cleanup_eh ()
5663 { return gimple_purge_all_dead_eh_edges (m_need_eh_cleanup); }
5665 private:
5666 struct ipa_func_body_info *m_fbi;
5667 vec<ipa_param_descriptor, va_gc> *m_descriptors;
5668 ipcp_transformation *m_ts;
5669 bool *m_something_changed;
5670 auto_bitmap m_need_eh_cleanup;
5673 edge
5674 ipcp_modif_dom_walker::before_dom_children (basic_block bb)
5676 gimple_stmt_iterator gsi;
5677 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
5679 gimple *stmt = gsi_stmt (gsi);
5680 tree rhs, val, t;
5681 HOST_WIDE_INT bit_offset;
5682 poly_int64 size;
5683 int index;
5684 bool by_ref, vce;
5686 if (!gimple_assign_load_p (stmt))
5687 continue;
5688 rhs = gimple_assign_rhs1 (stmt);
5689 if (!is_gimple_reg_type (TREE_TYPE (rhs)))
5690 continue;
5692 vce = false;
5693 t = rhs;
5694 while (handled_component_p (t))
5696 /* V_C_E can do things like convert an array of integers to one
5697 bigger integer and similar things we do not handle below. */
5698 if (TREE_CODE (t) == VIEW_CONVERT_EXPR)
5700 vce = true;
5701 break;
5703 t = TREE_OPERAND (t, 0);
5705 if (vce)
5706 continue;
5708 if (!ipa_load_from_parm_agg (m_fbi, m_descriptors, stmt, rhs, &index,
5709 &bit_offset, &size, &by_ref))
5710 continue;
5711 unsigned unit_offset = bit_offset / BITS_PER_UNIT;
5712 ipa_argagg_value_list avl (m_ts);
5713 tree v = avl.get_value (index, unit_offset, by_ref);
5715 if (!v
5716 || maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (v))), size))
5717 continue;
5719 gcc_checking_assert (is_gimple_ip_invariant (v));
5720 if (!useless_type_conversion_p (TREE_TYPE (rhs), TREE_TYPE (v)))
5722 if (fold_convertible_p (TREE_TYPE (rhs), v))
5723 val = fold_build1 (NOP_EXPR, TREE_TYPE (rhs), v);
5724 else if (TYPE_SIZE (TREE_TYPE (rhs))
5725 == TYPE_SIZE (TREE_TYPE (v)))
5726 val = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (rhs), v);
5727 else
5729 if (dump_file)
5731 fprintf (dump_file, " const ");
5732 print_generic_expr (dump_file, v);
5733 fprintf (dump_file, " can't be converted to type of ");
5734 print_generic_expr (dump_file, rhs);
5735 fprintf (dump_file, "\n");
5737 continue;
5740 else
5741 val = v;
5743 if (dump_file && (dump_flags & TDF_DETAILS))
5745 fprintf (dump_file, "Modifying stmt:\n ");
5746 print_gimple_stmt (dump_file, stmt, 0);
5748 gimple_assign_set_rhs_from_tree (&gsi, val);
5749 update_stmt (stmt);
5751 if (dump_file && (dump_flags & TDF_DETAILS))
5753 fprintf (dump_file, "into:\n ");
5754 print_gimple_stmt (dump_file, stmt, 0);
5755 fprintf (dump_file, "\n");
5758 *m_something_changed = true;
5759 if (maybe_clean_eh_stmt (stmt))
5760 bitmap_set_bit (m_need_eh_cleanup, bb->index);
5762 return NULL;
5765 /* Return true if we have recorded VALUE and MASK about PARM.
5766 Set VALUE and MASk accordingly. */
5768 bool
5769 ipcp_get_parm_bits (tree parm, tree *value, widest_int *mask)
5771 cgraph_node *cnode = cgraph_node::get (current_function_decl);
5772 ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
5773 if (!ts || vec_safe_length (ts->bits) == 0)
5774 return false;
5776 int i = ts->get_param_index (current_function_decl, parm);
5777 if (i < 0)
5778 return false;
5779 clone_info *cinfo = clone_info::get (cnode);
5780 if (cinfo && cinfo->param_adjustments)
5782 i = cinfo->param_adjustments->get_original_index (i);
5783 if (i < 0)
5784 return false;
5787 vec<ipa_bits *, va_gc> &bits = *ts->bits;
5788 if (!bits[i])
5789 return false;
5790 *mask = bits[i]->mask;
5791 *value = wide_int_to_tree (TREE_TYPE (parm), bits[i]->value);
5792 return true;
5795 /* Update bits info of formal parameters of NODE as described in TS. */
5797 static void
5798 ipcp_update_bits (struct cgraph_node *node, ipcp_transformation *ts)
5800 if (vec_safe_is_empty (ts->bits))
5801 return;
5802 vec<ipa_bits *, va_gc> &bits = *ts->bits;
5803 unsigned count = bits.length ();
5804 if (!count)
5805 return;
5807 auto_vec<int, 16> new_indices;
5808 bool need_remapping = false;
5809 clone_info *cinfo = clone_info::get (node);
5810 if (cinfo && cinfo->param_adjustments)
5812 cinfo->param_adjustments->get_updated_indices (&new_indices);
5813 need_remapping = true;
5815 auto_vec <tree, 16> parm_decls;
5816 push_function_arg_decls (&parm_decls, node->decl);
5818 for (unsigned i = 0; i < count; ++i)
5820 tree parm;
5821 if (need_remapping)
5823 if (i >= new_indices.length ())
5824 continue;
5825 int idx = new_indices[i];
5826 if (idx < 0)
5827 continue;
5828 parm = parm_decls[idx];
5830 else
5831 parm = parm_decls[i];
5832 gcc_checking_assert (parm);
5835 if (!bits[i]
5836 || !(INTEGRAL_TYPE_P (TREE_TYPE (parm))
5837 || POINTER_TYPE_P (TREE_TYPE (parm)))
5838 || !is_gimple_reg (parm))
5839 continue;
5841 tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl), parm);
5842 if (!ddef)
5843 continue;
5845 if (dump_file)
5847 fprintf (dump_file, "Adjusting mask for param %u to ", i);
5848 print_hex (bits[i]->mask, dump_file);
5849 fprintf (dump_file, "\n");
5852 if (INTEGRAL_TYPE_P (TREE_TYPE (ddef)))
5854 unsigned prec = TYPE_PRECISION (TREE_TYPE (ddef));
5855 signop sgn = TYPE_SIGN (TREE_TYPE (ddef));
5857 wide_int nonzero_bits = wide_int::from (bits[i]->mask, prec, UNSIGNED)
5858 | wide_int::from (bits[i]->value, prec, sgn);
5859 set_nonzero_bits (ddef, nonzero_bits);
5861 else
5863 unsigned tem = bits[i]->mask.to_uhwi ();
5864 unsigned HOST_WIDE_INT bitpos = bits[i]->value.to_uhwi ();
5865 unsigned align = tem & -tem;
5866 unsigned misalign = bitpos & (align - 1);
5868 if (align > 1)
5870 if (dump_file)
5871 fprintf (dump_file, "Adjusting align: %u, misalign: %u\n", align, misalign);
5873 unsigned old_align, old_misalign;
5874 struct ptr_info_def *pi = get_ptr_info (ddef);
5875 bool old_known = get_ptr_info_alignment (pi, &old_align, &old_misalign);
5877 if (old_known
5878 && old_align > align)
5880 if (dump_file)
5882 fprintf (dump_file, "But alignment was already %u.\n", old_align);
5883 if ((old_misalign & (align - 1)) != misalign)
5884 fprintf (dump_file, "old_misalign (%u) and misalign (%u) mismatch\n",
5885 old_misalign, misalign);
5887 continue;
5890 if (old_known
5891 && ((misalign & (old_align - 1)) != old_misalign)
5892 && dump_file)
5893 fprintf (dump_file, "old_misalign (%u) and misalign (%u) mismatch\n",
5894 old_misalign, misalign);
5896 set_ptr_info_alignment (pi, align, misalign);
5902 /* Update value range of formal parameters of NODE as described in TS. */
5904 static void
5905 ipcp_update_vr (struct cgraph_node *node, ipcp_transformation *ts)
5907 if (vec_safe_is_empty (ts->m_vr))
5908 return;
5909 const vec<ipa_vr, va_gc> &vr = *ts->m_vr;
5910 unsigned count = vr.length ();
5911 if (!count)
5912 return;
5914 auto_vec<int, 16> new_indices;
5915 bool need_remapping = false;
5916 clone_info *cinfo = clone_info::get (node);
5917 if (cinfo && cinfo->param_adjustments)
5919 cinfo->param_adjustments->get_updated_indices (&new_indices);
5920 need_remapping = true;
5922 auto_vec <tree, 16> parm_decls;
5923 push_function_arg_decls (&parm_decls, node->decl);
5925 for (unsigned i = 0; i < count; ++i)
5927 tree parm;
5928 int remapped_idx;
5929 if (need_remapping)
5931 if (i >= new_indices.length ())
5932 continue;
5933 remapped_idx = new_indices[i];
5934 if (remapped_idx < 0)
5935 continue;
5937 else
5938 remapped_idx = i;
5940 parm = parm_decls[remapped_idx];
5942 gcc_checking_assert (parm);
5943 tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl), parm);
5945 if (!ddef || !is_gimple_reg (parm))
5946 continue;
5948 if (vr[i].known_p ())
5950 Value_Range tmp;
5951 vr[i].get_vrange (tmp);
5953 if (!tmp.undefined_p () && !tmp.varying_p ())
5955 if (dump_file)
5957 fprintf (dump_file, "Setting value range of param %u "
5958 "(now %i) ", i, remapped_idx);
5959 tmp.dump (dump_file);
5960 fprintf (dump_file, "]\n");
5962 set_range_info (ddef, tmp);
5968 /* IPCP transformation phase doing propagation of aggregate values. */
5970 unsigned int
5971 ipcp_transform_function (struct cgraph_node *node)
5973 struct ipa_func_body_info fbi;
5974 int param_count;
5976 gcc_checking_assert (cfun);
5977 gcc_checking_assert (current_function_decl);
5979 if (dump_file)
5980 fprintf (dump_file, "Modification phase of node %s\n",
5981 node->dump_name ());
5983 ipcp_transformation *ts = ipcp_get_transformation_summary (node);
5984 if (!ts
5985 || (vec_safe_is_empty (ts->m_agg_values)
5986 && vec_safe_is_empty (ts->bits)
5987 && vec_safe_is_empty (ts->m_vr)))
5988 return 0;
5990 ts->maybe_create_parm_idx_map (cfun->decl);
5991 ipcp_update_bits (node, ts);
5992 ipcp_update_vr (node, ts);
5993 if (vec_safe_is_empty (ts->m_agg_values))
5994 return 0;
5995 param_count = count_formal_params (node->decl);
5996 if (param_count == 0)
5997 return 0;
5999 adjust_agg_replacement_values (node, ts);
6000 if (vec_safe_is_empty (ts->m_agg_values))
6002 if (dump_file)
6003 fprintf (dump_file, " All affected aggregate parameters were either "
6004 "removed or converted into scalars, phase done.\n");
6005 return 0;
6007 if (dump_file)
6009 fprintf (dump_file, " Aggregate replacements:");
6010 ipa_argagg_value_list avs (ts);
6011 avs.dump (dump_file);
6014 fbi.node = node;
6015 fbi.info = NULL;
6016 fbi.bb_infos = vNULL;
6017 fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
6018 fbi.param_count = param_count;
6019 fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps);
6021 vec<ipa_param_descriptor, va_gc> *descriptors = NULL;
6022 vec_safe_grow_cleared (descriptors, param_count, true);
6023 ipa_populate_param_decls (node, *descriptors);
6024 bool modified_mem_access = false;
6025 calculate_dominance_info (CDI_DOMINATORS);
6026 ipcp_modif_dom_walker walker (&fbi, descriptors, ts, &modified_mem_access);
6027 walker.walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
6028 free_dominance_info (CDI_DOMINATORS);
6029 bool cfg_changed = walker.cleanup_eh ();
6031 int i;
6032 struct ipa_bb_info *bi;
6033 FOR_EACH_VEC_ELT (fbi.bb_infos, i, bi)
6034 free_ipa_bb_info (bi);
6035 fbi.bb_infos.release ();
6037 ipcp_transformation *s = ipcp_transformation_sum->get (node);
6038 s->m_agg_values = NULL;
6039 s->bits = NULL;
6040 s->m_vr = NULL;
6042 vec_free (descriptors);
6043 if (cfg_changed)
6044 delete_unreachable_blocks_update_callgraph (node, false);
6046 return modified_mem_access ? TODO_update_ssa_only_virtuals : 0;
6050 #include "gt-ipa-prop.h"