Also check type being cast to
[official-gcc.git] / gcc / ipa-prop.cc
blob4e9a307ad4dd9d26af67c4131df18777518a5d11
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 value_ranges used for IPA. Note that
113 the equiv bitmap is not hashed and is expected to be NULL. */
115 struct ipa_vr_ggc_hash_traits : public ggc_cache_remove <value_range *>
117 typedef value_range *value_type;
118 typedef value_range *compare_type;
119 static hashval_t
120 hash (const value_range *p)
122 tree min, max;
123 value_range_kind kind = get_legacy_range (*p, min, max);
124 inchash::hash hstate (kind);
125 inchash::add_expr (min, hstate);
126 inchash::add_expr (max, hstate);
127 return hstate.end ();
129 static bool
130 equal (const value_range *a, const value_range *b)
132 return (types_compatible_p (a->type (), b->type ())
133 && *a == *b);
135 static const bool empty_zero_p = true;
136 static void
137 mark_empty (value_range *&p)
139 p = NULL;
141 static bool
142 is_empty (const value_range *p)
144 return p == NULL;
146 static bool
147 is_deleted (const value_range *p)
149 return p == reinterpret_cast<const value_range *> (1);
151 static void
152 mark_deleted (value_range *&p)
154 p = reinterpret_cast<value_range *> (1);
158 /* Hash table for avoid repeated allocations of equal value_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 (vrange &r) const
203 m_storage->get_vrange (r, m_type);
206 void
207 ipa_vr::set_unknown ()
209 if (m_storage)
210 ggc_free (m_storage);
212 m_storage = NULL;
215 void
216 ipa_vr::streamer_read (lto_input_block *ib, data_in *data_in)
218 struct bitpack_d bp = streamer_read_bitpack (ib);
219 bool known = bp_unpack_value (&bp, 1);
220 if (known)
222 Value_Range vr;
223 streamer_read_value_range (ib, data_in, vr);
224 if (!m_storage || !m_storage->fits_p (vr))
226 if (m_storage)
227 ggc_free (m_storage);
228 m_storage = ggc_alloc_vrange_storage (vr);
230 m_storage->set_vrange (vr);
231 m_type = vr.type ();
233 else
235 m_storage = NULL;
236 m_type = NULL;
240 void
241 ipa_vr::streamer_write (output_block *ob) const
243 struct bitpack_d bp = bitpack_create (ob->main_stream);
244 bp_pack_value (&bp, !!m_storage, 1);
245 streamer_write_bitpack (&bp);
246 if (m_storage)
248 Value_Range vr (m_type);
249 m_storage->get_vrange (vr, m_type);
250 streamer_write_vrange (ob, vr);
254 void
255 ipa_vr::dump (FILE *out) const
257 if (known_p ())
259 Value_Range vr (m_type);
260 m_storage->get_vrange (vr, m_type);
261 vr.dump (out);
263 else
264 fprintf (out, "NO RANGE");
267 /* Return true if DECL_FUNCTION_SPECIFIC_OPTIMIZATION of the decl associated
268 with NODE should prevent us from analyzing it for the purposes of IPA-CP. */
270 static bool
271 ipa_func_spec_opts_forbid_analysis_p (struct cgraph_node *node)
273 tree fs_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (node->decl);
275 if (!fs_opts)
276 return false;
277 return !opt_for_fn (node->decl, optimize) || !opt_for_fn (node->decl, flag_ipa_cp);
280 /* Return index of the formal whose tree is PTREE in function which corresponds
281 to INFO. */
283 static int
284 ipa_get_param_decl_index_1 (vec<ipa_param_descriptor, va_gc> *descriptors,
285 tree ptree)
287 int i, count;
289 count = vec_safe_length (descriptors);
290 for (i = 0; i < count; i++)
291 if ((*descriptors)[i].decl_or_type == ptree)
292 return i;
294 return -1;
297 /* Return index of the formal whose tree is PTREE in function which corresponds
298 to INFO. */
301 ipa_get_param_decl_index (class ipa_node_params *info, tree ptree)
303 return ipa_get_param_decl_index_1 (info->descriptors, ptree);
306 /* Populate the param_decl field in parameter DESCRIPTORS that correspond to
307 NODE. */
309 static void
310 ipa_populate_param_decls (struct cgraph_node *node,
311 vec<ipa_param_descriptor, va_gc> &descriptors)
313 tree fndecl;
314 tree fnargs;
315 tree parm;
316 int param_num;
318 fndecl = node->decl;
319 gcc_assert (gimple_has_body_p (fndecl));
320 fnargs = DECL_ARGUMENTS (fndecl);
321 param_num = 0;
322 for (parm = fnargs; parm; parm = DECL_CHAIN (parm))
324 descriptors[param_num].decl_or_type = parm;
325 unsigned int cost = estimate_move_cost (TREE_TYPE (parm), true);
326 descriptors[param_num].move_cost = cost;
327 /* Watch overflow, move_cost is a bitfield. */
328 gcc_checking_assert (cost == descriptors[param_num].move_cost);
329 param_num++;
333 /* Return how many formal parameters FNDECL has. */
336 count_formal_params (tree fndecl)
338 tree parm;
339 int count = 0;
340 gcc_assert (gimple_has_body_p (fndecl));
342 for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
343 count++;
345 return count;
348 /* Return the declaration of Ith formal parameter of the function corresponding
349 to INFO. Note there is no setter function as this array is built just once
350 using ipa_initialize_node_params. */
352 void
353 ipa_dump_param (FILE *file, class ipa_node_params *info, int i)
355 fprintf (file, "param #%i", i);
356 if ((*info->descriptors)[i].decl_or_type)
358 fprintf (file, " ");
359 print_generic_expr (file, (*info->descriptors)[i].decl_or_type);
363 /* If necessary, allocate vector of parameter descriptors in info of NODE.
364 Return true if they were allocated, false if not. */
366 static bool
367 ipa_alloc_node_params (struct cgraph_node *node, int param_count)
369 ipa_node_params *info = ipa_node_params_sum->get_create (node);
371 if (!info->descriptors && param_count)
373 vec_safe_grow_cleared (info->descriptors, param_count, true);
374 return true;
376 else
377 return false;
380 /* Initialize the ipa_node_params structure associated with NODE by counting
381 the function parameters, creating the descriptors and populating their
382 param_decls. */
384 void
385 ipa_initialize_node_params (struct cgraph_node *node)
387 ipa_node_params *info = ipa_node_params_sum->get_create (node);
389 if (!info->descriptors
390 && ipa_alloc_node_params (node, count_formal_params (node->decl)))
391 ipa_populate_param_decls (node, *info->descriptors);
394 /* Print the jump functions associated with call graph edge CS to file F. */
396 static void
397 ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
399 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
400 int count = ipa_get_cs_argument_count (args);
402 for (int i = 0; i < count; i++)
404 struct ipa_jump_func *jump_func;
405 enum jump_func_type type;
407 jump_func = ipa_get_ith_jump_func (args, i);
408 type = jump_func->type;
410 fprintf (f, " param %d: ", i);
411 if (type == IPA_JF_UNKNOWN)
412 fprintf (f, "UNKNOWN\n");
413 else if (type == IPA_JF_CONST)
415 tree val = jump_func->value.constant.value;
416 fprintf (f, "CONST: ");
417 print_generic_expr (f, val);
418 if (TREE_CODE (val) == ADDR_EXPR
419 && TREE_CODE (TREE_OPERAND (val, 0)) == CONST_DECL)
421 fprintf (f, " -> ");
422 print_generic_expr (f, DECL_INITIAL (TREE_OPERAND (val, 0)));
424 fprintf (f, "\n");
426 else if (type == IPA_JF_PASS_THROUGH)
428 fprintf (f, "PASS THROUGH: ");
429 fprintf (f, "%d, op %s",
430 jump_func->value.pass_through.formal_id,
431 get_tree_code_name(jump_func->value.pass_through.operation));
432 if (jump_func->value.pass_through.operation != NOP_EXPR)
434 fprintf (f, " ");
435 print_generic_expr (f, jump_func->value.pass_through.operand);
437 if (jump_func->value.pass_through.agg_preserved)
438 fprintf (f, ", agg_preserved");
439 if (jump_func->value.pass_through.refdesc_decremented)
440 fprintf (f, ", refdesc_decremented");
441 fprintf (f, "\n");
443 else if (type == IPA_JF_ANCESTOR)
445 fprintf (f, "ANCESTOR: ");
446 fprintf (f, "%d, offset " HOST_WIDE_INT_PRINT_DEC,
447 jump_func->value.ancestor.formal_id,
448 jump_func->value.ancestor.offset);
449 if (jump_func->value.ancestor.agg_preserved)
450 fprintf (f, ", agg_preserved");
451 if (jump_func->value.ancestor.keep_null)
452 fprintf (f, ", keep_null");
453 fprintf (f, "\n");
456 if (jump_func->agg.items)
458 struct ipa_agg_jf_item *item;
459 int j;
461 fprintf (f, " Aggregate passed by %s:\n",
462 jump_func->agg.by_ref ? "reference" : "value");
463 FOR_EACH_VEC_ELT (*jump_func->agg.items, j, item)
465 fprintf (f, " offset: " HOST_WIDE_INT_PRINT_DEC ", ",
466 item->offset);
467 fprintf (f, "type: ");
468 print_generic_expr (f, item->type);
469 fprintf (f, ", ");
470 if (item->jftype == IPA_JF_PASS_THROUGH)
471 fprintf (f, "PASS THROUGH: %d,",
472 item->value.pass_through.formal_id);
473 else if (item->jftype == IPA_JF_LOAD_AGG)
475 fprintf (f, "LOAD AGG: %d",
476 item->value.pass_through.formal_id);
477 fprintf (f, " [offset: " HOST_WIDE_INT_PRINT_DEC ", by %s],",
478 item->value.load_agg.offset,
479 item->value.load_agg.by_ref ? "reference"
480 : "value");
483 if (item->jftype == IPA_JF_PASS_THROUGH
484 || item->jftype == IPA_JF_LOAD_AGG)
486 fprintf (f, " op %s",
487 get_tree_code_name (item->value.pass_through.operation));
488 if (item->value.pass_through.operation != NOP_EXPR)
490 fprintf (f, " ");
491 print_generic_expr (f, item->value.pass_through.operand);
494 else if (item->jftype == IPA_JF_CONST)
496 fprintf (f, "CONST: ");
497 print_generic_expr (f, item->value.constant);
499 else if (item->jftype == IPA_JF_UNKNOWN)
500 fprintf (f, "UNKNOWN: " HOST_WIDE_INT_PRINT_DEC " bits",
501 tree_to_uhwi (TYPE_SIZE (item->type)));
502 fprintf (f, "\n");
506 class ipa_polymorphic_call_context *ctx
507 = ipa_get_ith_polymorhic_call_context (args, i);
508 if (ctx && !ctx->useless_p ())
510 fprintf (f, " Context: ");
511 ctx->dump (dump_file);
514 if (jump_func->bits)
516 fprintf (f, " value: ");
517 print_hex (jump_func->bits->value, f);
518 fprintf (f, ", mask: ");
519 print_hex (jump_func->bits->mask, f);
520 fprintf (f, "\n");
522 else
523 fprintf (f, " Unknown bits\n");
525 if (jump_func->m_vr)
527 jump_func->m_vr->dump (f);
528 fprintf (f, "\n");
530 else
531 fprintf (f, " Unknown VR\n");
536 /* Print the jump functions of all arguments on all call graph edges going from
537 NODE to file F. */
539 void
540 ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
542 struct cgraph_edge *cs;
544 fprintf (f, " Jump functions of caller %s:\n", node->dump_name ());
545 for (cs = node->callees; cs; cs = cs->next_callee)
548 fprintf (f, " callsite %s -> %s : \n",
549 node->dump_name (),
550 cs->callee->dump_name ());
551 if (!ipa_edge_args_info_available_for_edge_p (cs))
552 fprintf (f, " no arg info\n");
553 else
554 ipa_print_node_jump_functions_for_edge (f, cs);
557 for (cs = node->indirect_calls; cs; cs = cs->next_callee)
559 class cgraph_indirect_call_info *ii;
561 ii = cs->indirect_info;
562 if (ii->agg_contents)
563 fprintf (f, " indirect %s callsite, calling param %i, "
564 "offset " HOST_WIDE_INT_PRINT_DEC ", %s",
565 ii->member_ptr ? "member ptr" : "aggregate",
566 ii->param_index, ii->offset,
567 ii->by_ref ? "by reference" : "by_value");
568 else
569 fprintf (f, " indirect %s callsite, calling param %i, "
570 "offset " HOST_WIDE_INT_PRINT_DEC,
571 ii->polymorphic ? "polymorphic" : "simple", ii->param_index,
572 ii->offset);
574 if (cs->call_stmt)
576 fprintf (f, ", for stmt ");
577 print_gimple_stmt (f, cs->call_stmt, 0, TDF_SLIM);
579 else
580 fprintf (f, "\n");
581 if (ii->polymorphic)
582 ii->context.dump (f);
583 if (!ipa_edge_args_info_available_for_edge_p (cs))
584 fprintf (f, " no arg info\n");
585 else
586 ipa_print_node_jump_functions_for_edge (f, cs);
590 /* Print ipa_jump_func data structures of all nodes in the call graph to F. */
592 void
593 ipa_print_all_jump_functions (FILE *f)
595 struct cgraph_node *node;
597 fprintf (f, "\nJump functions:\n");
598 FOR_EACH_FUNCTION (node)
600 ipa_print_node_jump_functions (f, node);
604 /* Set jfunc to be a know-really nothing jump function. */
606 static void
607 ipa_set_jf_unknown (struct ipa_jump_func *jfunc)
609 jfunc->type = IPA_JF_UNKNOWN;
612 /* Set JFUNC to be a copy of another jmp (to be used by jump function
613 combination code). The two functions will share their rdesc. */
615 static void
616 ipa_set_jf_cst_copy (struct ipa_jump_func *dst,
617 struct ipa_jump_func *src)
620 gcc_checking_assert (src->type == IPA_JF_CONST);
621 dst->type = IPA_JF_CONST;
622 dst->value.constant = src->value.constant;
625 /* Set JFUNC to be a constant jmp function. */
627 static void
628 ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
629 struct cgraph_edge *cs)
631 jfunc->type = IPA_JF_CONST;
632 jfunc->value.constant.value = unshare_expr_without_location (constant);
634 if (TREE_CODE (constant) == ADDR_EXPR
635 && (TREE_CODE (TREE_OPERAND (constant, 0)) == FUNCTION_DECL
636 || (VAR_P (TREE_OPERAND (constant, 0))
637 && TREE_STATIC (TREE_OPERAND (constant, 0)))))
639 struct ipa_cst_ref_desc *rdesc;
641 rdesc = ipa_refdesc_pool.allocate ();
642 rdesc->cs = cs;
643 rdesc->next_duplicate = NULL;
644 rdesc->refcount = 1;
645 jfunc->value.constant.rdesc = rdesc;
647 else
648 jfunc->value.constant.rdesc = NULL;
651 /* Set JFUNC to be a simple pass-through jump function. */
652 static void
653 ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
654 bool agg_preserved)
656 jfunc->type = IPA_JF_PASS_THROUGH;
657 jfunc->value.pass_through.operand = NULL_TREE;
658 jfunc->value.pass_through.formal_id = formal_id;
659 jfunc->value.pass_through.operation = NOP_EXPR;
660 jfunc->value.pass_through.agg_preserved = agg_preserved;
661 jfunc->value.pass_through.refdesc_decremented = false;
664 /* Set JFUNC to be an unary pass through jump function. */
666 static void
667 ipa_set_jf_unary_pass_through (struct ipa_jump_func *jfunc, int formal_id,
668 enum tree_code operation)
670 jfunc->type = IPA_JF_PASS_THROUGH;
671 jfunc->value.pass_through.operand = NULL_TREE;
672 jfunc->value.pass_through.formal_id = formal_id;
673 jfunc->value.pass_through.operation = operation;
674 jfunc->value.pass_through.agg_preserved = false;
675 jfunc->value.pass_through.refdesc_decremented = false;
677 /* Set JFUNC to be an arithmetic pass through jump function. */
679 static void
680 ipa_set_jf_arith_pass_through (struct ipa_jump_func *jfunc, int formal_id,
681 tree operand, enum tree_code operation)
683 jfunc->type = IPA_JF_PASS_THROUGH;
684 jfunc->value.pass_through.operand = unshare_expr_without_location (operand);
685 jfunc->value.pass_through.formal_id = formal_id;
686 jfunc->value.pass_through.operation = operation;
687 jfunc->value.pass_through.agg_preserved = false;
688 jfunc->value.pass_through.refdesc_decremented = false;
691 /* Set JFUNC to be an ancestor jump function. */
693 static void
694 ipa_set_ancestor_jf (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
695 int formal_id, bool agg_preserved, bool keep_null)
697 jfunc->type = IPA_JF_ANCESTOR;
698 jfunc->value.ancestor.formal_id = formal_id;
699 jfunc->value.ancestor.offset = offset;
700 jfunc->value.ancestor.agg_preserved = agg_preserved;
701 jfunc->value.ancestor.keep_null = keep_null;
704 /* Get IPA BB information about the given BB. FBI is the context of analyzis
705 of this function body. */
707 static struct ipa_bb_info *
708 ipa_get_bb_info (struct ipa_func_body_info *fbi, basic_block bb)
710 gcc_checking_assert (fbi);
711 return &fbi->bb_infos[bb->index];
714 /* Structure to be passed in between detect_type_change and
715 check_stmt_for_type_change. */
717 struct prop_type_change_info
719 /* Offset into the object where there is the virtual method pointer we are
720 looking for. */
721 HOST_WIDE_INT offset;
722 /* The declaration or SSA_NAME pointer of the base that we are checking for
723 type change. */
724 tree object;
725 /* Set to true if dynamic type change has been detected. */
726 bool type_maybe_changed;
729 /* Return true if STMT can modify a virtual method table pointer.
731 This function makes special assumptions about both constructors and
732 destructors which are all the functions that are allowed to alter the VMT
733 pointers. It assumes that destructors begin with assignment into all VMT
734 pointers and that constructors essentially look in the following way:
736 1) The very first thing they do is that they call constructors of ancestor
737 sub-objects that have them.
739 2) Then VMT pointers of this and all its ancestors is set to new values
740 corresponding to the type corresponding to the constructor.
742 3) Only afterwards, other stuff such as constructor of member sub-objects
743 and the code written by the user is run. Only this may include calling
744 virtual functions, directly or indirectly.
746 There is no way to call a constructor of an ancestor sub-object in any
747 other way.
749 This means that we do not have to care whether constructors get the correct
750 type information because they will always change it (in fact, if we define
751 the type to be given by the VMT pointer, it is undefined).
753 The most important fact to derive from the above is that if, for some
754 statement in the section 3, we try to detect whether the dynamic type has
755 changed, we can safely ignore all calls as we examine the function body
756 backwards until we reach statements in section 2 because these calls cannot
757 be ancestor constructors or destructors (if the input is not bogus) and so
758 do not change the dynamic type (this holds true only for automatically
759 allocated objects but at the moment we devirtualize only these). We then
760 must detect that statements in section 2 change the dynamic type and can try
761 to derive the new type. That is enough and we can stop, we will never see
762 the calls into constructors of sub-objects in this code. Therefore we can
763 safely ignore all call statements that we traverse.
766 static bool
767 stmt_may_be_vtbl_ptr_store (gimple *stmt)
769 if (is_gimple_call (stmt))
770 return false;
771 if (gimple_clobber_p (stmt))
772 return false;
773 else if (is_gimple_assign (stmt))
775 tree lhs = gimple_assign_lhs (stmt);
777 if (!AGGREGATE_TYPE_P (TREE_TYPE (lhs)))
779 if (flag_strict_aliasing
780 && !POINTER_TYPE_P (TREE_TYPE (lhs)))
781 return false;
783 if (TREE_CODE (lhs) == COMPONENT_REF
784 && !DECL_VIRTUAL_P (TREE_OPERAND (lhs, 1)))
785 return false;
786 /* In the future we might want to use get_ref_base_and_extent to find
787 if there is a field corresponding to the offset and if so, proceed
788 almost like if it was a component ref. */
791 return true;
794 /* Callback of walk_aliased_vdefs and a helper function for detect_type_change
795 to check whether a particular statement may modify the virtual table
796 pointerIt stores its result into DATA, which points to a
797 prop_type_change_info structure. */
799 static bool
800 check_stmt_for_type_change (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
802 gimple *stmt = SSA_NAME_DEF_STMT (vdef);
803 struct prop_type_change_info *tci = (struct prop_type_change_info *) data;
805 if (stmt_may_be_vtbl_ptr_store (stmt))
807 tci->type_maybe_changed = true;
808 return true;
810 else
811 return false;
814 /* See if ARG is PARAM_DECl describing instance passed by pointer
815 or reference in FUNCTION. Return false if the dynamic type may change
816 in between beggining of the function until CALL is invoked.
818 Generally functions are not allowed to change type of such instances,
819 but they call destructors. We assume that methods cannot destroy the THIS
820 pointer. Also as a special cases, constructor and destructors may change
821 type of the THIS pointer. */
823 static bool
824 param_type_may_change_p (tree function, tree arg, gimple *call)
826 /* Pure functions cannot do any changes on the dynamic type;
827 that require writting to memory. */
828 if (flags_from_decl_or_type (function) & (ECF_PURE | ECF_CONST))
829 return false;
830 /* We need to check if we are within inlined consturctor
831 or destructor (ideally we would have way to check that the
832 inline cdtor is actually working on ARG, but we don't have
833 easy tie on this, so punt on all non-pure cdtors.
834 We may also record the types of cdtors and once we know type
835 of the instance match them.
837 Also code unification optimizations may merge calls from
838 different blocks making return values unreliable. So
839 do nothing during late optimization. */
840 if (DECL_STRUCT_FUNCTION (function)->after_inlining)
841 return true;
842 if (TREE_CODE (arg) == SSA_NAME
843 && SSA_NAME_IS_DEFAULT_DEF (arg)
844 && TREE_CODE (SSA_NAME_VAR (arg)) == PARM_DECL)
846 /* Normal (non-THIS) argument. */
847 if ((SSA_NAME_VAR (arg) != DECL_ARGUMENTS (function)
848 || TREE_CODE (TREE_TYPE (function)) != METHOD_TYPE)
849 /* THIS pointer of an method - here we want to watch constructors
850 and destructors as those definitely may change the dynamic
851 type. */
852 || (TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE
853 && !DECL_CXX_CONSTRUCTOR_P (function)
854 && !DECL_CXX_DESTRUCTOR_P (function)
855 && (SSA_NAME_VAR (arg) == DECL_ARGUMENTS (function))))
857 /* Walk the inline stack and watch out for ctors/dtors. */
858 for (tree block = gimple_block (call); block && TREE_CODE (block) == BLOCK;
859 block = BLOCK_SUPERCONTEXT (block))
860 if (inlined_polymorphic_ctor_dtor_block_p (block, false))
861 return true;
862 return false;
865 return true;
868 /* Detect whether the dynamic type of ARG of COMP_TYPE has changed (before
869 callsite CALL) by looking for assignments to its virtual table pointer. If
870 it is, return true. ARG is the object itself (not a pointer
871 to it, unless dereferenced). BASE is the base of the memory access as
872 returned by get_ref_base_and_extent, as is the offset.
874 This is helper function for detect_type_change and detect_type_change_ssa
875 that does the heavy work which is usually unnecesary. */
877 static bool
878 detect_type_change_from_memory_writes (ipa_func_body_info *fbi, tree arg,
879 tree base, tree comp_type, gcall *call,
880 HOST_WIDE_INT offset)
882 struct prop_type_change_info tci;
883 ao_ref ao;
885 gcc_checking_assert (DECL_P (arg)
886 || TREE_CODE (arg) == MEM_REF
887 || handled_component_p (arg));
889 comp_type = TYPE_MAIN_VARIANT (comp_type);
891 /* Const calls cannot call virtual methods through VMT and so type changes do
892 not matter. */
893 if (!flag_devirtualize || !gimple_vuse (call)
894 /* Be sure expected_type is polymorphic. */
895 || !comp_type
896 || TREE_CODE (comp_type) != RECORD_TYPE
897 || !TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type))
898 || !BINFO_VTABLE (TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type))))
899 return true;
901 if (fbi->aa_walk_budget == 0)
902 return false;
904 ao_ref_init (&ao, arg);
905 ao.base = base;
906 ao.offset = offset;
907 ao.size = POINTER_SIZE;
908 ao.max_size = ao.size;
910 tci.offset = offset;
911 tci.object = get_base_address (arg);
912 tci.type_maybe_changed = false;
914 int walked
915 = walk_aliased_vdefs (&ao, gimple_vuse (call), check_stmt_for_type_change,
916 &tci, NULL, NULL, fbi->aa_walk_budget);
917 if (walked >= 0)
918 fbi->aa_walk_budget -= walked;
919 else
920 fbi->aa_walk_budget = 0;
922 if (walked >= 0 && !tci.type_maybe_changed)
923 return false;
925 return true;
928 /* Detect whether the dynamic type of ARG of COMP_TYPE may have changed.
929 If it is, return true. ARG is the object itself (not a pointer
930 to it, unless dereferenced). BASE is the base of the memory access as
931 returned by get_ref_base_and_extent, as is the offset. */
933 static bool
934 detect_type_change (ipa_func_body_info *fbi, tree arg, tree base,
935 tree comp_type, gcall *call,
936 HOST_WIDE_INT offset)
938 if (!flag_devirtualize)
939 return false;
941 if (TREE_CODE (base) == MEM_REF
942 && !param_type_may_change_p (current_function_decl,
943 TREE_OPERAND (base, 0),
944 call))
945 return false;
946 return detect_type_change_from_memory_writes (fbi, arg, base, comp_type,
947 call, offset);
950 /* Like detect_type_change but ARG is supposed to be a non-dereferenced pointer
951 SSA name (its dereference will become the base and the offset is assumed to
952 be zero). */
954 static bool
955 detect_type_change_ssa (ipa_func_body_info *fbi, tree arg, tree comp_type,
956 gcall *call)
958 gcc_checking_assert (TREE_CODE (arg) == SSA_NAME);
959 if (!flag_devirtualize
960 || !POINTER_TYPE_P (TREE_TYPE (arg)))
961 return false;
963 if (!param_type_may_change_p (current_function_decl, arg, call))
964 return false;
966 arg = build2 (MEM_REF, ptr_type_node, arg,
967 build_int_cst (ptr_type_node, 0));
969 return detect_type_change_from_memory_writes (fbi, arg, arg, comp_type,
970 call, 0);
973 /* Callback of walk_aliased_vdefs. Flags that it has been invoked to the
974 boolean variable pointed to by DATA. */
976 static bool
977 mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
978 void *data)
980 bool *b = (bool *) data;
981 *b = true;
982 return true;
985 /* Find the nearest valid aa status for parameter specified by INDEX that
986 dominates BB. */
988 static struct ipa_param_aa_status *
989 find_dominating_aa_status (struct ipa_func_body_info *fbi, basic_block bb,
990 int index)
992 while (true)
994 bb = get_immediate_dominator (CDI_DOMINATORS, bb);
995 if (!bb)
996 return NULL;
997 struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
998 if (!bi->param_aa_statuses.is_empty ()
999 && bi->param_aa_statuses[index].valid)
1000 return &bi->param_aa_statuses[index];
1004 /* Get AA status structure for the given BB and parameter with INDEX. Allocate
1005 structures and/or intialize the result with a dominating description as
1006 necessary. */
1008 static struct ipa_param_aa_status *
1009 parm_bb_aa_status_for_bb (struct ipa_func_body_info *fbi, basic_block bb,
1010 int index)
1012 gcc_checking_assert (fbi);
1013 struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
1014 if (bi->param_aa_statuses.is_empty ())
1015 bi->param_aa_statuses.safe_grow_cleared (fbi->param_count, true);
1016 struct ipa_param_aa_status *paa = &bi->param_aa_statuses[index];
1017 if (!paa->valid)
1019 gcc_checking_assert (!paa->parm_modified
1020 && !paa->ref_modified
1021 && !paa->pt_modified);
1022 struct ipa_param_aa_status *dom_paa;
1023 dom_paa = find_dominating_aa_status (fbi, bb, index);
1024 if (dom_paa)
1025 *paa = *dom_paa;
1026 else
1027 paa->valid = true;
1030 return paa;
1033 /* Return true if a load from a formal parameter PARM_LOAD is known to retrieve
1034 a value known not to be modified in this function before reaching the
1035 statement STMT. FBI holds information about the function we have so far
1036 gathered but do not survive the summary building stage. */
1038 static bool
1039 parm_preserved_before_stmt_p (struct ipa_func_body_info *fbi, int index,
1040 gimple *stmt, tree parm_load)
1042 struct ipa_param_aa_status *paa;
1043 bool modified = false;
1044 ao_ref refd;
1046 tree base = get_base_address (parm_load);
1047 gcc_assert (TREE_CODE (base) == PARM_DECL);
1048 if (TREE_READONLY (base))
1049 return true;
1051 gcc_checking_assert (fbi);
1052 paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (stmt), index);
1053 if (paa->parm_modified || fbi->aa_walk_budget == 0)
1054 return false;
1056 gcc_checking_assert (gimple_vuse (stmt) != NULL_TREE);
1057 ao_ref_init (&refd, parm_load);
1058 int walked = walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified,
1059 &modified, NULL, NULL,
1060 fbi->aa_walk_budget);
1061 if (walked < 0)
1063 modified = true;
1064 fbi->aa_walk_budget = 0;
1066 else
1067 fbi->aa_walk_budget -= walked;
1068 if (paa && modified)
1069 paa->parm_modified = true;
1070 return !modified;
1073 /* If STMT is an assignment that loads a value from an parameter declaration,
1074 return the index of the parameter in ipa_node_params which has not been
1075 modified. Otherwise return -1. */
1077 static int
1078 load_from_unmodified_param (struct ipa_func_body_info *fbi,
1079 vec<ipa_param_descriptor, va_gc> *descriptors,
1080 gimple *stmt)
1082 int index;
1083 tree op1;
1085 if (!gimple_assign_single_p (stmt))
1086 return -1;
1088 op1 = gimple_assign_rhs1 (stmt);
1089 if (TREE_CODE (op1) != PARM_DECL)
1090 return -1;
1092 index = ipa_get_param_decl_index_1 (descriptors, op1);
1093 if (index < 0
1094 || !parm_preserved_before_stmt_p (fbi, index, stmt, op1))
1095 return -1;
1097 return index;
1100 /* Return true if memory reference REF (which must be a load through parameter
1101 with INDEX) loads data that are known to be unmodified in this function
1102 before reaching statement STMT. */
1104 static bool
1105 parm_ref_data_preserved_p (struct ipa_func_body_info *fbi,
1106 int index, gimple *stmt, tree ref)
1108 struct ipa_param_aa_status *paa;
1109 bool modified = false;
1110 ao_ref refd;
1112 gcc_checking_assert (fbi);
1113 paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (stmt), index);
1114 if (paa->ref_modified || fbi->aa_walk_budget == 0)
1115 return false;
1117 gcc_checking_assert (gimple_vuse (stmt));
1118 ao_ref_init (&refd, ref);
1119 int walked = walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified,
1120 &modified, NULL, NULL,
1121 fbi->aa_walk_budget);
1122 if (walked < 0)
1124 modified = true;
1125 fbi->aa_walk_budget = 0;
1127 else
1128 fbi->aa_walk_budget -= walked;
1129 if (modified)
1130 paa->ref_modified = true;
1131 return !modified;
1134 /* Return true if the data pointed to by PARM (which is a parameter with INDEX)
1135 is known to be unmodified in this function before reaching call statement
1136 CALL into which it is passed. FBI describes the function body. */
1138 static bool
1139 parm_ref_data_pass_through_p (struct ipa_func_body_info *fbi, int index,
1140 gimple *call, tree parm)
1142 bool modified = false;
1143 ao_ref refd;
1145 /* It's unnecessary to calculate anything about memory contnets for a const
1146 function because it is not goin to use it. But do not cache the result
1147 either. Also, no such calculations for non-pointers. */
1148 if (!gimple_vuse (call)
1149 || !POINTER_TYPE_P (TREE_TYPE (parm)))
1150 return false;
1152 struct ipa_param_aa_status *paa = parm_bb_aa_status_for_bb (fbi,
1153 gimple_bb (call),
1154 index);
1155 if (paa->pt_modified || fbi->aa_walk_budget == 0)
1156 return false;
1158 ao_ref_init_from_ptr_and_size (&refd, parm, NULL_TREE);
1159 int walked = walk_aliased_vdefs (&refd, gimple_vuse (call), mark_modified,
1160 &modified, NULL, NULL,
1161 fbi->aa_walk_budget);
1162 if (walked < 0)
1164 fbi->aa_walk_budget = 0;
1165 modified = true;
1167 else
1168 fbi->aa_walk_budget -= walked;
1169 if (modified)
1170 paa->pt_modified = true;
1171 return !modified;
1174 /* Return true if we can prove that OP is a memory reference loading
1175 data from an aggregate passed as a parameter.
1177 The function works in two modes. If GUARANTEED_UNMODIFIED is NULL, it return
1178 false if it cannot prove that the value has not been modified before the
1179 load in STMT. If GUARANTEED_UNMODIFIED is not NULL, it will return true even
1180 if it cannot prove the value has not been modified, in that case it will
1181 store false to *GUARANTEED_UNMODIFIED, otherwise it will store true there.
1183 INFO and PARMS_AINFO describe parameters of the current function (but the
1184 latter can be NULL), STMT is the load statement. If function returns true,
1185 *INDEX_P, *OFFSET_P and *BY_REF is filled with the parameter index, offset
1186 within the aggregate and whether it is a load from a value passed by
1187 reference respectively.
1189 Return false if the offset divided by BITS_PER_UNIT would not fit into an
1190 unsigned int. */
1192 bool
1193 ipa_load_from_parm_agg (struct ipa_func_body_info *fbi,
1194 vec<ipa_param_descriptor, va_gc> *descriptors,
1195 gimple *stmt, tree op, int *index_p,
1196 HOST_WIDE_INT *offset_p, poly_int64 *size_p,
1197 bool *by_ref_p, bool *guaranteed_unmodified)
1199 int index;
1200 HOST_WIDE_INT size;
1201 bool reverse;
1202 tree base = get_ref_base_and_extent_hwi (op, offset_p, &size, &reverse);
1204 if (!base
1205 || (*offset_p / BITS_PER_UNIT) > UINT_MAX)
1206 return false;
1208 /* We can not propagate across volatile loads. */
1209 if (TREE_THIS_VOLATILE (op))
1210 return false;
1212 if (DECL_P (base))
1214 int index = ipa_get_param_decl_index_1 (descriptors, base);
1215 if (index >= 0
1216 && parm_preserved_before_stmt_p (fbi, index, stmt, op))
1218 *index_p = index;
1219 *by_ref_p = false;
1220 if (size_p)
1221 *size_p = size;
1222 if (guaranteed_unmodified)
1223 *guaranteed_unmodified = true;
1224 return true;
1226 return false;
1229 if (TREE_CODE (base) != MEM_REF
1230 || TREE_CODE (TREE_OPERAND (base, 0)) != SSA_NAME
1231 || !integer_zerop (TREE_OPERAND (base, 1)))
1232 return false;
1234 if (SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (base, 0)))
1236 tree parm = SSA_NAME_VAR (TREE_OPERAND (base, 0));
1237 index = ipa_get_param_decl_index_1 (descriptors, parm);
1239 else
1241 /* This branch catches situations where a pointer parameter is not a
1242 gimple register, for example:
1244 void hip7(S*) (struct S * p)
1246 void (*<T2e4>) (struct S *) D.1867;
1247 struct S * p.1;
1249 <bb 2>:
1250 p.1_1 = p;
1251 D.1867_2 = p.1_1->f;
1252 D.1867_2 ();
1253 gdp = &p;
1256 gimple *def = SSA_NAME_DEF_STMT (TREE_OPERAND (base, 0));
1257 index = load_from_unmodified_param (fbi, descriptors, def);
1260 if (index >= 0)
1262 bool data_preserved = parm_ref_data_preserved_p (fbi, index, stmt, op);
1263 if (!data_preserved && !guaranteed_unmodified)
1264 return false;
1266 *index_p = index;
1267 *by_ref_p = true;
1268 if (size_p)
1269 *size_p = size;
1270 if (guaranteed_unmodified)
1271 *guaranteed_unmodified = data_preserved;
1272 return true;
1274 return false;
1277 /* If STMT is an assignment that loads a value from a parameter declaration,
1278 or from an aggregate passed as the parameter either by value or reference,
1279 return the index of the parameter in ipa_node_params. Otherwise return -1.
1281 FBI holds gathered information about the function. INFO describes
1282 parameters of the function, STMT is the assignment statement. If it is a
1283 memory load from an aggregate, *OFFSET_P is filled with offset within the
1284 aggregate, and *BY_REF_P specifies whether the aggregate is passed by
1285 reference. */
1287 static int
1288 load_from_unmodified_param_or_agg (struct ipa_func_body_info *fbi,
1289 class ipa_node_params *info,
1290 gimple *stmt,
1291 HOST_WIDE_INT *offset_p,
1292 bool *by_ref_p)
1294 int index = load_from_unmodified_param (fbi, info->descriptors, stmt);
1295 poly_int64 size;
1297 /* Load value from a parameter declaration. */
1298 if (index >= 0)
1300 *offset_p = -1;
1301 return index;
1304 if (!gimple_assign_load_p (stmt))
1305 return -1;
1307 tree rhs = gimple_assign_rhs1 (stmt);
1309 /* Skip memory reference containing VIEW_CONVERT_EXPR. */
1310 for (tree t = rhs; handled_component_p (t); t = TREE_OPERAND (t, 0))
1311 if (TREE_CODE (t) == VIEW_CONVERT_EXPR)
1312 return -1;
1314 /* Skip memory reference containing bit-field. */
1315 if (TREE_CODE (rhs) == BIT_FIELD_REF
1316 || contains_bitfld_component_ref_p (rhs))
1317 return -1;
1319 if (!ipa_load_from_parm_agg (fbi, info->descriptors, stmt, rhs, &index,
1320 offset_p, &size, by_ref_p))
1321 return -1;
1323 gcc_assert (!maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (rhs))),
1324 size));
1325 if (!*by_ref_p)
1327 tree param_type = ipa_get_type (info, index);
1329 if (!param_type || !AGGREGATE_TYPE_P (param_type))
1330 return -1;
1332 else if (TREE_THIS_VOLATILE (rhs))
1333 return -1;
1335 return index;
1338 /* Walk pointer adjustemnts from OP (such as POINTER_PLUS and ADDR_EXPR)
1339 to find original pointer. Initialize RET to the pointer which results from
1340 the walk.
1341 If offset is known return true and initialize OFFSET_RET. */
1343 bool
1344 unadjusted_ptr_and_unit_offset (tree op, tree *ret, poly_int64 *offset_ret)
1346 poly_int64 offset = 0;
1347 bool offset_known = true;
1348 int i;
1350 for (i = 0; i < param_ipa_jump_function_lookups; i++)
1352 if (TREE_CODE (op) == ADDR_EXPR)
1354 poly_int64 extra_offset = 0;
1355 tree base = get_addr_base_and_unit_offset (TREE_OPERAND (op, 0),
1356 &offset);
1357 if (!base)
1359 base = get_base_address (TREE_OPERAND (op, 0));
1360 if (TREE_CODE (base) != MEM_REF)
1361 break;
1362 offset_known = false;
1364 else
1366 if (TREE_CODE (base) != MEM_REF)
1367 break;
1368 offset += extra_offset;
1370 op = TREE_OPERAND (base, 0);
1371 if (mem_ref_offset (base).to_shwi (&extra_offset))
1372 offset += extra_offset;
1373 else
1374 offset_known = false;
1376 else if (TREE_CODE (op) == SSA_NAME
1377 && !SSA_NAME_IS_DEFAULT_DEF (op))
1379 gimple *pstmt = SSA_NAME_DEF_STMT (op);
1381 if (gimple_assign_single_p (pstmt))
1382 op = gimple_assign_rhs1 (pstmt);
1383 else if (is_gimple_assign (pstmt)
1384 && gimple_assign_rhs_code (pstmt) == POINTER_PLUS_EXPR)
1386 poly_int64 extra_offset = 0;
1387 if (ptrdiff_tree_p (gimple_assign_rhs2 (pstmt),
1388 &extra_offset))
1389 offset += extra_offset;
1390 else
1391 offset_known = false;
1392 op = gimple_assign_rhs1 (pstmt);
1394 else
1395 break;
1397 else
1398 break;
1400 *ret = op;
1401 *offset_ret = offset;
1402 return offset_known;
1405 /* Given that an actual argument is an SSA_NAME (given in NAME) and is a result
1406 of an assignment statement STMT, try to determine whether we are actually
1407 handling any of the following cases and construct an appropriate jump
1408 function into JFUNC if so:
1410 1) The passed value is loaded from a formal parameter which is not a gimple
1411 register (most probably because it is addressable, the value has to be
1412 scalar) and we can guarantee the value has not changed. This case can
1413 therefore be described by a simple pass-through jump function. For example:
1415 foo (int a)
1417 int a.0;
1419 a.0_2 = a;
1420 bar (a.0_2);
1422 2) The passed value can be described by a simple arithmetic pass-through
1423 jump function. E.g.
1425 foo (int a)
1427 int D.2064;
1429 D.2064_4 = a.1(D) + 4;
1430 bar (D.2064_4);
1432 This case can also occur in combination of the previous one, e.g.:
1434 foo (int a, int z)
1436 int a.0;
1437 int D.2064;
1439 a.0_3 = a;
1440 D.2064_4 = a.0_3 + 4;
1441 foo (D.2064_4);
1443 3) The passed value is an address of an object within another one (which
1444 also passed by reference). Such situations are described by an ancestor
1445 jump function and describe situations such as:
1447 B::foo() (struct B * const this)
1449 struct A * D.1845;
1451 D.1845_2 = &this_1(D)->D.1748;
1452 A::bar (D.1845_2);
1454 INFO is the structure describing individual parameters access different
1455 stages of IPA optimizations. PARMS_AINFO contains the information that is
1456 only needed for intraprocedural analysis. */
1458 static void
1459 compute_complex_assign_jump_func (struct ipa_func_body_info *fbi,
1460 class ipa_node_params *info,
1461 struct ipa_jump_func *jfunc,
1462 gcall *call, gimple *stmt, tree name,
1463 tree param_type)
1465 HOST_WIDE_INT offset, size;
1466 tree op1, tc_ssa, base, ssa;
1467 bool reverse;
1468 int index;
1470 op1 = gimple_assign_rhs1 (stmt);
1472 if (TREE_CODE (op1) == SSA_NAME)
1474 if (SSA_NAME_IS_DEFAULT_DEF (op1))
1475 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (op1));
1476 else
1477 index = load_from_unmodified_param (fbi, info->descriptors,
1478 SSA_NAME_DEF_STMT (op1));
1479 tc_ssa = op1;
1481 else
1483 index = load_from_unmodified_param (fbi, info->descriptors, stmt);
1484 tc_ssa = gimple_assign_lhs (stmt);
1487 if (index >= 0)
1489 switch (gimple_assign_rhs_class (stmt))
1491 case GIMPLE_BINARY_RHS:
1493 tree op2 = gimple_assign_rhs2 (stmt);
1494 if (!is_gimple_ip_invariant (op2)
1495 || ((TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))
1496 != tcc_comparison)
1497 && !useless_type_conversion_p (TREE_TYPE (name),
1498 TREE_TYPE (op1))))
1499 return;
1501 ipa_set_jf_arith_pass_through (jfunc, index, op2,
1502 gimple_assign_rhs_code (stmt));
1503 break;
1505 case GIMPLE_SINGLE_RHS:
1507 bool agg_p = parm_ref_data_pass_through_p (fbi, index, call,
1508 tc_ssa);
1509 ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
1510 break;
1512 case GIMPLE_UNARY_RHS:
1513 if (!CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt)))
1514 ipa_set_jf_unary_pass_through (jfunc, index,
1515 gimple_assign_rhs_code (stmt));
1516 default:;
1518 return;
1521 if (TREE_CODE (op1) != ADDR_EXPR)
1522 return;
1523 op1 = TREE_OPERAND (op1, 0);
1524 base = get_ref_base_and_extent_hwi (op1, &offset, &size, &reverse);
1525 offset_int mem_offset;
1526 if (!base
1527 || TREE_CODE (base) != MEM_REF
1528 || !mem_ref_offset (base).is_constant (&mem_offset))
1529 return;
1530 offset += mem_offset.to_short_addr () * BITS_PER_UNIT;
1531 ssa = TREE_OPERAND (base, 0);
1532 if (TREE_CODE (ssa) != SSA_NAME
1533 || !SSA_NAME_IS_DEFAULT_DEF (ssa)
1534 || offset < 0)
1535 return;
1537 /* Dynamic types are changed in constructors and destructors. */
1538 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (ssa));
1539 if (index >= 0 && param_type && POINTER_TYPE_P (param_type))
1540 ipa_set_ancestor_jf (jfunc, offset, index,
1541 parm_ref_data_pass_through_p (fbi, index, call, ssa),
1542 false);
1545 /* Extract the base, offset and MEM_REF expression from a statement ASSIGN if
1546 it looks like:
1548 iftmp.1_3 = &obj_2(D)->D.1762;
1550 The base of the MEM_REF must be a default definition SSA NAME of a
1551 parameter. Return NULL_TREE if it looks otherwise. If case of success, the
1552 whole MEM_REF expression is returned and the offset calculated from any
1553 handled components and the MEM_REF itself is stored into *OFFSET. The whole
1554 RHS stripped off the ADDR_EXPR is stored into *OBJ_P. */
1556 static tree
1557 get_ancestor_addr_info (gimple *assign, tree *obj_p, HOST_WIDE_INT *offset)
1559 HOST_WIDE_INT size;
1560 tree expr, parm, obj;
1561 bool reverse;
1563 if (!gimple_assign_single_p (assign))
1564 return NULL_TREE;
1565 expr = gimple_assign_rhs1 (assign);
1567 if (TREE_CODE (expr) != ADDR_EXPR)
1568 return NULL_TREE;
1569 expr = TREE_OPERAND (expr, 0);
1570 obj = expr;
1571 expr = get_ref_base_and_extent_hwi (expr, offset, &size, &reverse);
1573 offset_int mem_offset;
1574 if (!expr
1575 || TREE_CODE (expr) != MEM_REF
1576 || !mem_ref_offset (expr).is_constant (&mem_offset))
1577 return NULL_TREE;
1578 parm = TREE_OPERAND (expr, 0);
1579 if (TREE_CODE (parm) != SSA_NAME
1580 || !SSA_NAME_IS_DEFAULT_DEF (parm)
1581 || TREE_CODE (SSA_NAME_VAR (parm)) != PARM_DECL)
1582 return NULL_TREE;
1584 *offset += mem_offset.to_short_addr () * BITS_PER_UNIT;
1585 *obj_p = obj;
1586 return expr;
1590 /* Given that an actual argument is an SSA_NAME that is a result of a phi
1591 statement PHI, try to find out whether NAME is in fact a
1592 multiple-inheritance typecast from a descendant into an ancestor of a formal
1593 parameter and thus can be described by an ancestor jump function and if so,
1594 write the appropriate function into JFUNC.
1596 Essentially we want to match the following pattern:
1598 if (obj_2(D) != 0B)
1599 goto <bb 3>;
1600 else
1601 goto <bb 4>;
1603 <bb 3>:
1604 iftmp.1_3 = &obj_2(D)->D.1762;
1606 <bb 4>:
1607 # iftmp.1_1 = PHI <iftmp.1_3(3), 0B(2)>
1608 D.1879_6 = middleman_1 (iftmp.1_1, i_5(D));
1609 return D.1879_6; */
1611 static void
1612 compute_complex_ancestor_jump_func (struct ipa_func_body_info *fbi,
1613 class ipa_node_params *info,
1614 struct ipa_jump_func *jfunc,
1615 gcall *call, gphi *phi)
1617 HOST_WIDE_INT offset;
1618 gimple *assign;
1619 basic_block phi_bb, assign_bb, cond_bb;
1620 tree tmp, parm, expr, obj;
1621 int index, i;
1623 if (gimple_phi_num_args (phi) != 2)
1624 return;
1626 if (integer_zerop (PHI_ARG_DEF (phi, 1)))
1627 tmp = PHI_ARG_DEF (phi, 0);
1628 else if (integer_zerop (PHI_ARG_DEF (phi, 0)))
1629 tmp = PHI_ARG_DEF (phi, 1);
1630 else
1631 return;
1632 if (TREE_CODE (tmp) != SSA_NAME
1633 || SSA_NAME_IS_DEFAULT_DEF (tmp)
1634 || !POINTER_TYPE_P (TREE_TYPE (tmp))
1635 || TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) != RECORD_TYPE)
1636 return;
1638 assign = SSA_NAME_DEF_STMT (tmp);
1639 assign_bb = gimple_bb (assign);
1640 if (!single_pred_p (assign_bb))
1641 return;
1642 expr = get_ancestor_addr_info (assign, &obj, &offset);
1643 if (!expr)
1644 return;
1645 parm = TREE_OPERAND (expr, 0);
1646 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (parm));
1647 if (index < 0)
1648 return;
1650 cond_bb = single_pred (assign_bb);
1651 gcond *cond = safe_dyn_cast <gcond *> (*gsi_last_bb (cond_bb));
1652 if (!cond
1653 || gimple_cond_code (cond) != NE_EXPR
1654 || gimple_cond_lhs (cond) != parm
1655 || !integer_zerop (gimple_cond_rhs (cond)))
1656 return;
1658 phi_bb = gimple_bb (phi);
1659 for (i = 0; i < 2; i++)
1661 basic_block pred = EDGE_PRED (phi_bb, i)->src;
1662 if (pred != assign_bb && pred != cond_bb)
1663 return;
1666 ipa_set_ancestor_jf (jfunc, offset, index,
1667 parm_ref_data_pass_through_p (fbi, index, call, parm),
1668 true);
1671 /* Inspect the given TYPE and return true iff it has the same structure (the
1672 same number of fields of the same types) as a C++ member pointer. If
1673 METHOD_PTR and DELTA are non-NULL, store the trees representing the
1674 corresponding fields there. */
1676 static bool
1677 type_like_member_ptr_p (tree type, tree *method_ptr, tree *delta)
1679 tree fld;
1681 if (TREE_CODE (type) != RECORD_TYPE)
1682 return false;
1684 fld = TYPE_FIELDS (type);
1685 if (!fld || !POINTER_TYPE_P (TREE_TYPE (fld))
1686 || TREE_CODE (TREE_TYPE (TREE_TYPE (fld))) != METHOD_TYPE
1687 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
1688 return false;
1690 if (method_ptr)
1691 *method_ptr = fld;
1693 fld = DECL_CHAIN (fld);
1694 if (!fld || INTEGRAL_TYPE_P (fld)
1695 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
1696 return false;
1697 if (delta)
1698 *delta = fld;
1700 if (DECL_CHAIN (fld))
1701 return false;
1703 return true;
1706 /* If RHS is an SSA_NAME and it is defined by a simple copy assign statement,
1707 return the rhs of its defining statement, and this statement is stored in
1708 *RHS_STMT. Otherwise return RHS as it is. */
1710 static inline tree
1711 get_ssa_def_if_simple_copy (tree rhs, gimple **rhs_stmt)
1713 while (TREE_CODE (rhs) == SSA_NAME && !SSA_NAME_IS_DEFAULT_DEF (rhs))
1715 gimple *def_stmt = SSA_NAME_DEF_STMT (rhs);
1717 if (gimple_assign_single_p (def_stmt))
1718 rhs = gimple_assign_rhs1 (def_stmt);
1719 else
1720 break;
1721 *rhs_stmt = def_stmt;
1723 return rhs;
1726 /* Simple linked list, describing contents of an aggregate before call. */
1728 struct ipa_known_agg_contents_list
1730 /* Offset and size of the described part of the aggregate. */
1731 HOST_WIDE_INT offset, size;
1733 /* Type of the described part of the aggregate. */
1734 tree type;
1736 /* Known constant value or jump function data describing contents. */
1737 struct ipa_load_agg_data value;
1739 /* Pointer to the next structure in the list. */
1740 struct ipa_known_agg_contents_list *next;
1743 /* Add an aggregate content item into a linked list of
1744 ipa_known_agg_contents_list structure, in which all elements
1745 are sorted ascendingly by offset. */
1747 static inline void
1748 add_to_agg_contents_list (struct ipa_known_agg_contents_list **plist,
1749 struct ipa_known_agg_contents_list *item)
1751 struct ipa_known_agg_contents_list *list = *plist;
1753 for (; list; list = list->next)
1755 if (list->offset >= item->offset)
1756 break;
1758 plist = &list->next;
1761 item->next = list;
1762 *plist = item;
1765 /* Check whether a given aggregate content is clobbered by certain element in
1766 a linked list of ipa_known_agg_contents_list. */
1768 static inline bool
1769 clobber_by_agg_contents_list_p (struct ipa_known_agg_contents_list *list,
1770 struct ipa_known_agg_contents_list *item)
1772 for (; list; list = list->next)
1774 if (list->offset >= item->offset)
1775 return list->offset < item->offset + item->size;
1777 if (list->offset + list->size > item->offset)
1778 return true;
1781 return false;
1784 /* Build aggregate jump function from LIST, assuming there are exactly
1785 VALUE_COUNT entries there and that offset of the passed argument
1786 is ARG_OFFSET and store it into JFUNC. */
1788 static void
1789 build_agg_jump_func_from_list (struct ipa_known_agg_contents_list *list,
1790 int value_count, HOST_WIDE_INT arg_offset,
1791 struct ipa_jump_func *jfunc)
1793 vec_safe_reserve (jfunc->agg.items, value_count, true);
1794 for (; list; list = list->next)
1796 struct ipa_agg_jf_item item;
1797 tree operand = list->value.pass_through.operand;
1799 if (list->value.pass_through.formal_id >= 0)
1801 /* Content value is derived from some formal paramerter. */
1802 if (list->value.offset >= 0)
1803 item.jftype = IPA_JF_LOAD_AGG;
1804 else
1805 item.jftype = IPA_JF_PASS_THROUGH;
1807 item.value.load_agg = list->value;
1808 if (operand)
1809 item.value.pass_through.operand
1810 = unshare_expr_without_location (operand);
1812 else if (operand)
1814 /* Content value is known constant. */
1815 item.jftype = IPA_JF_CONST;
1816 item.value.constant = unshare_expr_without_location (operand);
1818 else
1819 continue;
1821 item.type = list->type;
1822 gcc_assert (tree_to_shwi (TYPE_SIZE (list->type)) == list->size);
1824 item.offset = list->offset - arg_offset;
1825 gcc_assert ((item.offset % BITS_PER_UNIT) == 0);
1827 jfunc->agg.items->quick_push (item);
1831 /* Given an assignment statement STMT, try to collect information into
1832 AGG_VALUE that will be used to construct jump function for RHS of the
1833 assignment, from which content value of an aggregate part comes.
1835 Besides constant and simple pass-through jump functions, also try to
1836 identify whether it matches the following pattern that can be described by
1837 a load-value-from-aggregate jump function, which is a derivative of simple
1838 pass-through jump function.
1840 foo (int *p)
1844 *(q_5 + 4) = *(p_3(D) + 28) op 1;
1845 bar (q_5);
1848 Here IPA_LOAD_AGG_DATA data structure is informative enough to describe
1849 constant, simple pass-through and load-vale-from-aggregate. If value
1850 is constant, it will be kept in field OPERAND, and field FORMAL_ID is
1851 set to -1. For simple pass-through and load-value-from-aggregate, field
1852 FORMAL_ID specifies the related formal parameter index, and field
1853 OFFSET can be used to distinguish them, -1 means simple pass-through,
1854 otherwise means load-value-from-aggregate. */
1856 static void
1857 analyze_agg_content_value (struct ipa_func_body_info *fbi,
1858 struct ipa_load_agg_data *agg_value,
1859 gimple *stmt)
1861 tree lhs = gimple_assign_lhs (stmt);
1862 tree rhs1 = gimple_assign_rhs1 (stmt);
1863 enum tree_code code;
1864 int index = -1;
1866 /* Initialize jump function data for the aggregate part. */
1867 memset (agg_value, 0, sizeof (*agg_value));
1868 agg_value->pass_through.operation = NOP_EXPR;
1869 agg_value->pass_through.formal_id = -1;
1870 agg_value->offset = -1;
1872 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs)) /* TODO: Support aggregate type. */
1873 || TREE_THIS_VOLATILE (lhs)
1874 || TREE_CODE (lhs) == BIT_FIELD_REF
1875 || contains_bitfld_component_ref_p (lhs))
1876 return;
1878 /* Skip SSA copies. */
1879 while (gimple_assign_rhs_class (stmt) == GIMPLE_SINGLE_RHS)
1881 if (TREE_CODE (rhs1) != SSA_NAME || SSA_NAME_IS_DEFAULT_DEF (rhs1))
1882 break;
1884 stmt = SSA_NAME_DEF_STMT (rhs1);
1885 if (!is_gimple_assign (stmt))
1886 break;
1888 rhs1 = gimple_assign_rhs1 (stmt);
1891 if (gphi *phi = dyn_cast<gphi *> (stmt))
1893 /* Also special case like the following (a is a formal parameter):
1895 _12 = *a_11(D).dim[0].stride;
1897 # iftmp.22_9 = PHI <_12(2), 1(3)>
1899 parm.6.dim[0].stride = iftmp.22_9;
1901 __x_MOD_foo (&parm.6, b_31(D));
1903 The aggregate function describing parm.6.dim[0].stride is encoded as a
1904 PASS-THROUGH jump function with ASSERT_EXPR operation whith operand 1
1905 (the constant from the PHI node). */
1907 if (gimple_phi_num_args (phi) != 2)
1908 return;
1909 tree arg0 = gimple_phi_arg_def (phi, 0);
1910 tree arg1 = gimple_phi_arg_def (phi, 1);
1911 tree operand;
1913 if (is_gimple_ip_invariant (arg1))
1915 operand = arg1;
1916 rhs1 = arg0;
1918 else if (is_gimple_ip_invariant (arg0))
1920 operand = arg0;
1921 rhs1 = arg1;
1923 else
1924 return;
1926 rhs1 = get_ssa_def_if_simple_copy (rhs1, &stmt);
1927 if (!is_gimple_assign (stmt))
1928 return;
1930 code = ASSERT_EXPR;
1931 agg_value->pass_through.operand = operand;
1933 else if (is_gimple_assign (stmt))
1935 code = gimple_assign_rhs_code (stmt);
1936 switch (gimple_assign_rhs_class (stmt))
1938 case GIMPLE_SINGLE_RHS:
1939 if (is_gimple_ip_invariant (rhs1))
1941 agg_value->pass_through.operand = rhs1;
1942 return;
1944 code = NOP_EXPR;
1945 break;
1947 case GIMPLE_UNARY_RHS:
1948 /* NOTE: A GIMPLE_UNARY_RHS operation might not be tcc_unary
1949 (truth_not_expr is example), GIMPLE_BINARY_RHS does not imply
1950 tcc_binary, this subtleness is somewhat misleading.
1952 Since tcc_unary is widely used in IPA-CP code to check an operation
1953 with one operand, here we only allow tc_unary operation to avoid
1954 possible problem. Then we can use (opclass == tc_unary) or not to
1955 distinguish unary and binary. */
1956 if (TREE_CODE_CLASS (code) != tcc_unary || CONVERT_EXPR_CODE_P (code))
1957 return;
1959 rhs1 = get_ssa_def_if_simple_copy (rhs1, &stmt);
1960 break;
1962 case GIMPLE_BINARY_RHS:
1964 gimple *rhs1_stmt = stmt;
1965 gimple *rhs2_stmt = stmt;
1966 tree rhs2 = gimple_assign_rhs2 (stmt);
1968 rhs1 = get_ssa_def_if_simple_copy (rhs1, &rhs1_stmt);
1969 rhs2 = get_ssa_def_if_simple_copy (rhs2, &rhs2_stmt);
1971 if (is_gimple_ip_invariant (rhs2))
1973 agg_value->pass_through.operand = rhs2;
1974 stmt = rhs1_stmt;
1976 else if (is_gimple_ip_invariant (rhs1))
1978 if (TREE_CODE_CLASS (code) == tcc_comparison)
1979 code = swap_tree_comparison (code);
1980 else if (!commutative_tree_code (code))
1981 return;
1983 agg_value->pass_through.operand = rhs1;
1984 stmt = rhs2_stmt;
1985 rhs1 = rhs2;
1987 else
1988 return;
1990 if (TREE_CODE_CLASS (code) != tcc_comparison
1991 && !useless_type_conversion_p (TREE_TYPE (lhs),
1992 TREE_TYPE (rhs1)))
1993 return;
1995 break;
1997 default:
1998 return;
2001 else
2002 return;
2004 if (TREE_CODE (rhs1) != SSA_NAME)
2005 index = load_from_unmodified_param_or_agg (fbi, fbi->info, stmt,
2006 &agg_value->offset,
2007 &agg_value->by_ref);
2008 else if (SSA_NAME_IS_DEFAULT_DEF (rhs1))
2009 index = ipa_get_param_decl_index (fbi->info, SSA_NAME_VAR (rhs1));
2011 if (index >= 0)
2013 if (agg_value->offset >= 0)
2014 agg_value->type = TREE_TYPE (rhs1);
2015 agg_value->pass_through.formal_id = index;
2016 agg_value->pass_through.operation = code;
2018 else
2019 agg_value->pass_through.operand = NULL_TREE;
2022 /* If STMT is a memory store to the object whose address is BASE, extract
2023 information (offset, size, and value) into CONTENT, and return true,
2024 otherwise we conservatively assume the whole object is modified with
2025 unknown content, and return false. CHECK_REF means that access to object
2026 is expected to be in form of MEM_REF expression. */
2028 static bool
2029 extract_mem_content (struct ipa_func_body_info *fbi,
2030 gimple *stmt, tree base, bool check_ref,
2031 struct ipa_known_agg_contents_list *content)
2033 HOST_WIDE_INT lhs_offset, lhs_size;
2034 bool reverse;
2036 if (!is_gimple_assign (stmt))
2037 return false;
2039 tree lhs = gimple_assign_lhs (stmt);
2040 tree lhs_base = get_ref_base_and_extent_hwi (lhs, &lhs_offset, &lhs_size,
2041 &reverse);
2042 if (!lhs_base)
2043 return false;
2045 if (check_ref)
2047 if (TREE_CODE (lhs_base) != MEM_REF
2048 || TREE_OPERAND (lhs_base, 0) != base
2049 || !integer_zerop (TREE_OPERAND (lhs_base, 1)))
2050 return false;
2052 else if (lhs_base != base)
2053 return false;
2055 content->offset = lhs_offset;
2056 content->size = lhs_size;
2057 content->type = TREE_TYPE (lhs);
2058 content->next = NULL;
2060 analyze_agg_content_value (fbi, &content->value, stmt);
2061 return true;
2064 /* Traverse statements from CALL backwards, scanning whether an aggregate given
2065 in ARG is filled in constants or values that are derived from caller's
2066 formal parameter in the way described by some kinds of jump functions. FBI
2067 is the context of the caller function for interprocedural analysis. ARG can
2068 either be an aggregate expression or a pointer to an aggregate. ARG_TYPE is
2069 the type of the aggregate, JFUNC is the jump function for the aggregate. */
2071 static void
2072 determine_known_aggregate_parts (struct ipa_func_body_info *fbi,
2073 gcall *call, tree arg,
2074 tree arg_type,
2075 struct ipa_jump_func *jfunc)
2077 struct ipa_known_agg_contents_list *list = NULL, *all_list = NULL;
2078 bitmap visited = NULL;
2079 int item_count = 0, value_count = 0;
2080 HOST_WIDE_INT arg_offset, arg_size;
2081 tree arg_base;
2082 bool check_ref, by_ref;
2083 ao_ref r;
2084 int max_agg_items = opt_for_fn (fbi->node->decl, param_ipa_max_agg_items);
2086 if (max_agg_items == 0)
2087 return;
2089 /* The function operates in three stages. First, we prepare check_ref, r,
2090 arg_base and arg_offset based on what is actually passed as an actual
2091 argument. */
2093 if (POINTER_TYPE_P (arg_type))
2095 by_ref = true;
2096 if (TREE_CODE (arg) == SSA_NAME)
2098 tree type_size;
2099 if (!tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (arg_type)))
2100 || !POINTER_TYPE_P (TREE_TYPE (arg)))
2101 return;
2102 check_ref = true;
2103 arg_base = arg;
2104 arg_offset = 0;
2105 type_size = TYPE_SIZE (TREE_TYPE (arg_type));
2106 arg_size = tree_to_uhwi (type_size);
2107 ao_ref_init_from_ptr_and_size (&r, arg_base, NULL_TREE);
2109 else if (TREE_CODE (arg) == ADDR_EXPR)
2111 bool reverse;
2113 arg = TREE_OPERAND (arg, 0);
2114 arg_base = get_ref_base_and_extent_hwi (arg, &arg_offset,
2115 &arg_size, &reverse);
2116 if (!arg_base)
2117 return;
2118 if (DECL_P (arg_base))
2120 check_ref = false;
2121 ao_ref_init (&r, arg_base);
2123 else
2124 return;
2126 else
2127 return;
2129 else
2131 bool reverse;
2133 gcc_checking_assert (AGGREGATE_TYPE_P (TREE_TYPE (arg)));
2135 by_ref = false;
2136 check_ref = false;
2137 arg_base = get_ref_base_and_extent_hwi (arg, &arg_offset,
2138 &arg_size, &reverse);
2139 if (!arg_base)
2140 return;
2142 ao_ref_init (&r, arg);
2145 /* Second stage traverses virtual SSA web backwards starting from the call
2146 statement, only looks at individual dominating virtual operand (its
2147 definition dominates the call), as long as it is confident that content
2148 of the aggregate is affected by definition of the virtual operand, it
2149 builds a sorted linked list of ipa_agg_jf_list describing that. */
2151 for (tree dom_vuse = gimple_vuse (call);
2152 dom_vuse && fbi->aa_walk_budget > 0;)
2154 gimple *stmt = SSA_NAME_DEF_STMT (dom_vuse);
2156 if (gimple_code (stmt) == GIMPLE_PHI)
2158 dom_vuse = get_continuation_for_phi (stmt, &r, true,
2159 fbi->aa_walk_budget,
2160 &visited, false, NULL, NULL);
2161 continue;
2164 fbi->aa_walk_budget--;
2165 if (stmt_may_clobber_ref_p_1 (stmt, &r))
2167 struct ipa_known_agg_contents_list *content
2168 = XALLOCA (struct ipa_known_agg_contents_list);
2170 if (!extract_mem_content (fbi, stmt, arg_base, check_ref, content))
2171 break;
2173 /* Now we get a dominating virtual operand, and need to check
2174 whether its value is clobbered any other dominating one. */
2175 if ((content->value.pass_through.formal_id >= 0
2176 || content->value.pass_through.operand)
2177 && !clobber_by_agg_contents_list_p (all_list, content)
2178 /* Since IPA-CP stores results with unsigned int offsets, we can
2179 discard those which would not fit now before we stream them to
2180 WPA. */
2181 && (content->offset + content->size - arg_offset
2182 <= (HOST_WIDE_INT) UINT_MAX * BITS_PER_UNIT))
2184 struct ipa_known_agg_contents_list *copy
2185 = XALLOCA (struct ipa_known_agg_contents_list);
2187 /* Add to the list consisting of only dominating virtual
2188 operands, whose definitions can finally reach the call. */
2189 add_to_agg_contents_list (&list, (*copy = *content, copy));
2191 if (++value_count == max_agg_items)
2192 break;
2195 /* Add to the list consisting of all dominating virtual operands. */
2196 add_to_agg_contents_list (&all_list, content);
2198 if (++item_count == 2 * max_agg_items)
2199 break;
2201 dom_vuse = gimple_vuse (stmt);
2204 if (visited)
2205 BITMAP_FREE (visited);
2207 /* Third stage just goes over the list and creates an appropriate vector of
2208 ipa_agg_jf_item structures out of it, of course only if there are
2209 any meaningful items to begin with. */
2211 if (value_count)
2213 jfunc->agg.by_ref = by_ref;
2214 build_agg_jump_func_from_list (list, value_count, arg_offset, jfunc);
2219 /* Return the Ith param type of callee associated with call graph
2220 edge E. */
2222 tree
2223 ipa_get_callee_param_type (struct cgraph_edge *e, int i)
2225 int n;
2226 tree type = (e->callee
2227 ? TREE_TYPE (e->callee->decl)
2228 : gimple_call_fntype (e->call_stmt));
2229 tree t = TYPE_ARG_TYPES (type);
2231 for (n = 0; n < i; n++)
2233 if (!t)
2234 break;
2235 t = TREE_CHAIN (t);
2237 if (t && t != void_list_node)
2238 return TREE_VALUE (t);
2239 if (!e->callee)
2240 return NULL;
2241 t = DECL_ARGUMENTS (e->callee->decl);
2242 for (n = 0; n < i; n++)
2244 if (!t)
2245 return NULL;
2246 t = TREE_CHAIN (t);
2248 if (t)
2249 return TREE_TYPE (t);
2250 return NULL;
2253 /* Return ipa_bits with VALUE and MASK values, which can be either a newly
2254 allocated structure or a previously existing one shared with other jump
2255 functions and/or transformation summaries. */
2257 ipa_bits *
2258 ipa_get_ipa_bits_for_value (const widest_int &value, const widest_int &mask)
2260 ipa_bits tmp;
2261 tmp.value = value;
2262 tmp.mask = mask;
2264 ipa_bits **slot = ipa_bits_hash_table->find_slot (&tmp, INSERT);
2265 if (*slot)
2266 return *slot;
2268 ipa_bits *res = ggc_alloc<ipa_bits> ();
2269 res->value = value;
2270 res->mask = mask;
2271 *slot = res;
2273 return res;
2276 /* Assign to JF a pointer to ipa_bits structure with VALUE and MASK. Use hash
2277 table in order to avoid creating multiple same ipa_bits structures. */
2279 static void
2280 ipa_set_jfunc_bits (ipa_jump_func *jf, const widest_int &value,
2281 const widest_int &mask)
2283 jf->bits = ipa_get_ipa_bits_for_value (value, mask);
2286 /* Return a pointer to a value_range just like *TMP, but either find it in
2287 ipa_vr_hash_table or allocate it in GC memory. TMP->equiv must be NULL. */
2289 static value_range *
2290 ipa_get_value_range (value_range *tmp)
2292 value_range **slot = ipa_vr_hash_table->find_slot (tmp, INSERT);
2293 if (*slot)
2294 return *slot;
2296 value_range *vr = new (ggc_alloc<value_range> ()) value_range;
2297 *vr = *tmp;
2298 *slot = vr;
2300 return vr;
2303 /* Return a pointer to a value range consisting of TYPE, MIN, MAX and an empty
2304 equiv set. Use hash table in order to avoid creating multiple same copies of
2305 value_ranges. */
2307 static value_range *
2308 ipa_get_value_range (enum value_range_kind kind, tree min, tree max)
2310 value_range tmp (TREE_TYPE (min),
2311 wi::to_wide (min), wi::to_wide (max), kind);
2312 return ipa_get_value_range (&tmp);
2315 /* Assign to JF a pointer to a value_range structure with TYPE, MIN and MAX and
2316 a NULL equiv bitmap. Use hash table in order to avoid creating multiple
2317 same value_range structures. */
2319 static void
2320 ipa_set_jfunc_vr (ipa_jump_func *jf, enum value_range_kind type,
2321 tree min, tree max)
2323 jf->m_vr = ipa_get_value_range (type, min, max);
2326 /* Assign to JF a pointer to a value_range just like TMP but either fetch a
2327 copy from ipa_vr_hash_table or allocate a new on in GC memory. */
2329 static void
2330 ipa_set_jfunc_vr (ipa_jump_func *jf, value_range *tmp)
2332 jf->m_vr = ipa_get_value_range (tmp);
2335 /* Compute jump function for all arguments of callsite CS and insert the
2336 information in the jump_functions array in the ipa_edge_args corresponding
2337 to this callsite. */
2339 static void
2340 ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
2341 struct cgraph_edge *cs)
2343 ipa_node_params *info = ipa_node_params_sum->get (cs->caller);
2344 ipa_edge_args *args = ipa_edge_args_sum->get_create (cs);
2345 gcall *call = cs->call_stmt;
2346 int n, arg_num = gimple_call_num_args (call);
2347 bool useful_context = false;
2348 value_range vr;
2350 if (arg_num == 0 || args->jump_functions)
2351 return;
2352 vec_safe_grow_cleared (args->jump_functions, arg_num, true);
2353 if (flag_devirtualize)
2354 vec_safe_grow_cleared (args->polymorphic_call_contexts, arg_num, true);
2356 if (gimple_call_internal_p (call))
2357 return;
2358 if (ipa_func_spec_opts_forbid_analysis_p (cs->caller))
2359 return;
2361 for (n = 0; n < arg_num; n++)
2363 struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, n);
2364 tree arg = gimple_call_arg (call, n);
2365 tree param_type = ipa_get_callee_param_type (cs, n);
2366 if (flag_devirtualize && POINTER_TYPE_P (TREE_TYPE (arg)))
2368 tree instance;
2369 class ipa_polymorphic_call_context context (cs->caller->decl,
2370 arg, cs->call_stmt,
2371 &instance);
2372 context.get_dynamic_type (instance, arg, NULL, cs->call_stmt,
2373 &fbi->aa_walk_budget);
2374 *ipa_get_ith_polymorhic_call_context (args, n) = context;
2375 if (!context.useless_p ())
2376 useful_context = true;
2379 if (POINTER_TYPE_P (TREE_TYPE (arg)))
2381 bool addr_nonzero = false;
2382 bool strict_overflow = false;
2384 if (TREE_CODE (arg) == SSA_NAME
2385 && param_type
2386 && get_range_query (cfun)->range_of_expr (vr, arg)
2387 && vr.nonzero_p ())
2388 addr_nonzero = true;
2389 else if (tree_single_nonzero_warnv_p (arg, &strict_overflow))
2390 addr_nonzero = true;
2392 if (addr_nonzero)
2394 tree z = build_int_cst (TREE_TYPE (arg), 0);
2395 ipa_set_jfunc_vr (jfunc, VR_ANTI_RANGE, z, z);
2397 else
2398 gcc_assert (!jfunc->m_vr);
2400 else
2402 if (TREE_CODE (arg) == SSA_NAME
2403 && param_type
2404 /* Limit the ranger query to integral types as the rest
2405 of this file uses value_range's, which only hold
2406 integers and pointers. */
2407 && irange::supports_p (TREE_TYPE (arg))
2408 && irange::supports_p (param_type)
2409 && get_range_query (cfun)->range_of_expr (vr, arg)
2410 && !vr.undefined_p ())
2412 value_range resvr = vr;
2413 range_cast (resvr, param_type);
2414 if (!resvr.undefined_p () && !resvr.varying_p ())
2415 ipa_set_jfunc_vr (jfunc, &resvr);
2416 else
2417 gcc_assert (!jfunc->m_vr);
2419 else
2420 gcc_assert (!jfunc->m_vr);
2423 if (INTEGRAL_TYPE_P (TREE_TYPE (arg))
2424 && (TREE_CODE (arg) == SSA_NAME || TREE_CODE (arg) == INTEGER_CST))
2426 if (TREE_CODE (arg) == SSA_NAME)
2427 ipa_set_jfunc_bits (jfunc, 0,
2428 widest_int::from (get_nonzero_bits (arg),
2429 TYPE_SIGN (TREE_TYPE (arg))));
2430 else
2431 ipa_set_jfunc_bits (jfunc, wi::to_widest (arg), 0);
2433 else if (POINTER_TYPE_P (TREE_TYPE (arg)))
2435 unsigned HOST_WIDE_INT bitpos;
2436 unsigned align;
2438 get_pointer_alignment_1 (arg, &align, &bitpos);
2439 widest_int mask = wi::bit_and_not
2440 (wi::mask<widest_int> (TYPE_PRECISION (TREE_TYPE (arg)), false),
2441 align / BITS_PER_UNIT - 1);
2442 widest_int value = bitpos / BITS_PER_UNIT;
2443 ipa_set_jfunc_bits (jfunc, value, mask);
2445 else
2446 gcc_assert (!jfunc->bits);
2448 if (is_gimple_ip_invariant (arg)
2449 || (VAR_P (arg)
2450 && is_global_var (arg)
2451 && TREE_READONLY (arg)))
2452 ipa_set_jf_constant (jfunc, arg, cs);
2453 else if (!is_gimple_reg_type (TREE_TYPE (arg))
2454 && TREE_CODE (arg) == PARM_DECL)
2456 int index = ipa_get_param_decl_index (info, arg);
2458 gcc_assert (index >=0);
2459 /* Aggregate passed by value, check for pass-through, otherwise we
2460 will attempt to fill in aggregate contents later in this
2461 for cycle. */
2462 if (parm_preserved_before_stmt_p (fbi, index, call, arg))
2464 ipa_set_jf_simple_pass_through (jfunc, index, false);
2465 continue;
2468 else if (TREE_CODE (arg) == SSA_NAME)
2470 if (SSA_NAME_IS_DEFAULT_DEF (arg))
2472 int index = ipa_get_param_decl_index (info, SSA_NAME_VAR (arg));
2473 if (index >= 0)
2475 bool agg_p;
2476 agg_p = parm_ref_data_pass_through_p (fbi, index, call, arg);
2477 ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
2480 else
2482 gimple *stmt = SSA_NAME_DEF_STMT (arg);
2483 if (is_gimple_assign (stmt))
2484 compute_complex_assign_jump_func (fbi, info, jfunc,
2485 call, stmt, arg, param_type);
2486 else if (gimple_code (stmt) == GIMPLE_PHI)
2487 compute_complex_ancestor_jump_func (fbi, info, jfunc,
2488 call,
2489 as_a <gphi *> (stmt));
2493 /* If ARG is pointer, we cannot use its type to determine the type of aggregate
2494 passed (because type conversions are ignored in gimple). Usually we can
2495 safely get type from function declaration, but in case of K&R prototypes or
2496 variadic functions we can try our luck with type of the pointer passed.
2497 TODO: Since we look for actual initialization of the memory object, we may better
2498 work out the type based on the memory stores we find. */
2499 if (!param_type)
2500 param_type = TREE_TYPE (arg);
2502 if ((jfunc->type != IPA_JF_PASS_THROUGH
2503 || !ipa_get_jf_pass_through_agg_preserved (jfunc))
2504 && (jfunc->type != IPA_JF_ANCESTOR
2505 || !ipa_get_jf_ancestor_agg_preserved (jfunc))
2506 && (AGGREGATE_TYPE_P (TREE_TYPE (arg))
2507 || POINTER_TYPE_P (param_type)))
2508 determine_known_aggregate_parts (fbi, call, arg, param_type, jfunc);
2510 if (!useful_context)
2511 vec_free (args->polymorphic_call_contexts);
2514 /* Compute jump functions for all edges - both direct and indirect - outgoing
2515 from BB. */
2517 static void
2518 ipa_compute_jump_functions_for_bb (struct ipa_func_body_info *fbi, basic_block bb)
2520 struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
2521 int i;
2522 struct cgraph_edge *cs;
2524 FOR_EACH_VEC_ELT_REVERSE (bi->cg_edges, i, cs)
2526 struct cgraph_node *callee = cs->callee;
2528 if (callee)
2530 callee = callee->ultimate_alias_target ();
2531 /* We do not need to bother analyzing calls to unknown functions
2532 unless they may become known during lto/whopr. */
2533 if (!callee->definition && !flag_lto
2534 && !gimple_call_fnspec (cs->call_stmt).known_p ())
2535 continue;
2537 ipa_compute_jump_functions_for_edge (fbi, cs);
2541 /* If STMT looks like a statement loading a value from a member pointer formal
2542 parameter, return that parameter and store the offset of the field to
2543 *OFFSET_P, if it is non-NULL. Otherwise return NULL (but *OFFSET_P still
2544 might be clobbered). If USE_DELTA, then we look for a use of the delta
2545 field rather than the pfn. */
2547 static tree
2548 ipa_get_stmt_member_ptr_load_param (gimple *stmt, bool use_delta,
2549 HOST_WIDE_INT *offset_p)
2551 tree rhs, rec, ref_field, ref_offset, fld, ptr_field, delta_field;
2553 if (!gimple_assign_single_p (stmt))
2554 return NULL_TREE;
2556 rhs = gimple_assign_rhs1 (stmt);
2557 if (TREE_CODE (rhs) == COMPONENT_REF)
2559 ref_field = TREE_OPERAND (rhs, 1);
2560 rhs = TREE_OPERAND (rhs, 0);
2562 else
2563 ref_field = NULL_TREE;
2564 if (TREE_CODE (rhs) != MEM_REF)
2565 return NULL_TREE;
2566 rec = TREE_OPERAND (rhs, 0);
2567 if (TREE_CODE (rec) != ADDR_EXPR)
2568 return NULL_TREE;
2569 rec = TREE_OPERAND (rec, 0);
2570 if (TREE_CODE (rec) != PARM_DECL
2571 || !type_like_member_ptr_p (TREE_TYPE (rec), &ptr_field, &delta_field))
2572 return NULL_TREE;
2573 ref_offset = TREE_OPERAND (rhs, 1);
2575 if (use_delta)
2576 fld = delta_field;
2577 else
2578 fld = ptr_field;
2579 if (offset_p)
2580 *offset_p = int_bit_position (fld);
2582 if (ref_field)
2584 if (integer_nonzerop (ref_offset))
2585 return NULL_TREE;
2586 return ref_field == fld ? rec : NULL_TREE;
2588 else
2589 return tree_int_cst_equal (byte_position (fld), ref_offset) ? rec
2590 : NULL_TREE;
2593 /* Returns true iff T is an SSA_NAME defined by a statement. */
2595 static bool
2596 ipa_is_ssa_with_stmt_def (tree t)
2598 if (TREE_CODE (t) == SSA_NAME
2599 && !SSA_NAME_IS_DEFAULT_DEF (t))
2600 return true;
2601 else
2602 return false;
2605 /* Find the indirect call graph edge corresponding to STMT and mark it as a
2606 call to a parameter number PARAM_INDEX. NODE is the caller. Return the
2607 indirect call graph edge.
2608 If POLYMORPHIC is true record is as a destination of polymorphic call. */
2610 static struct cgraph_edge *
2611 ipa_note_param_call (struct cgraph_node *node, int param_index,
2612 gcall *stmt, bool polymorphic)
2614 struct cgraph_edge *cs;
2616 cs = node->get_edge (stmt);
2617 cs->indirect_info->param_index = param_index;
2618 cs->indirect_info->agg_contents = 0;
2619 cs->indirect_info->member_ptr = 0;
2620 cs->indirect_info->guaranteed_unmodified = 0;
2621 ipa_node_params *info = ipa_node_params_sum->get (node);
2622 ipa_set_param_used_by_indirect_call (info, param_index, true);
2623 if (cs->indirect_info->polymorphic || polymorphic)
2624 ipa_set_param_used_by_polymorphic_call (info, param_index, true);
2625 return cs;
2628 /* Analyze the CALL and examine uses of formal parameters of the caller NODE
2629 (described by INFO). PARMS_AINFO is a pointer to a vector containing
2630 intermediate information about each formal parameter. Currently it checks
2631 whether the call calls a pointer that is a formal parameter and if so, the
2632 parameter is marked with the called flag and an indirect call graph edge
2633 describing the call is created. This is very simple for ordinary pointers
2634 represented in SSA but not-so-nice when it comes to member pointers. The
2635 ugly part of this function does nothing more than trying to match the
2636 pattern of such a call. An example of such a pattern is the gimple dump
2637 below, the call is on the last line:
2639 <bb 2>:
2640 f$__delta_5 = f.__delta;
2641 f$__pfn_24 = f.__pfn;
2644 <bb 2>:
2645 f$__delta_5 = MEM[(struct *)&f];
2646 f$__pfn_24 = MEM[(struct *)&f + 4B];
2648 and a few lines below:
2650 <bb 5>
2651 D.2496_3 = (int) f$__pfn_24;
2652 D.2497_4 = D.2496_3 & 1;
2653 if (D.2497_4 != 0)
2654 goto <bb 3>;
2655 else
2656 goto <bb 4>;
2658 <bb 6>:
2659 D.2500_7 = (unsigned int) f$__delta_5;
2660 D.2501_8 = &S + D.2500_7;
2661 D.2502_9 = (int (*__vtbl_ptr_type) (void) * *) D.2501_8;
2662 D.2503_10 = *D.2502_9;
2663 D.2504_12 = f$__pfn_24 + -1;
2664 D.2505_13 = (unsigned int) D.2504_12;
2665 D.2506_14 = D.2503_10 + D.2505_13;
2666 D.2507_15 = *D.2506_14;
2667 iftmp.11_16 = (String:: *) D.2507_15;
2669 <bb 7>:
2670 # iftmp.11_1 = PHI <iftmp.11_16(3), f$__pfn_24(2)>
2671 D.2500_19 = (unsigned int) f$__delta_5;
2672 D.2508_20 = &S + D.2500_19;
2673 D.2493_21 = iftmp.11_1 (D.2508_20, 4);
2675 Such patterns are results of simple calls to a member pointer:
2677 int doprinting (int (MyString::* f)(int) const)
2679 MyString S ("somestring");
2681 return (S.*f)(4);
2684 Moreover, the function also looks for called pointers loaded from aggregates
2685 passed by value or reference. */
2687 static void
2688 ipa_analyze_indirect_call_uses (struct ipa_func_body_info *fbi, gcall *call,
2689 tree target)
2691 class ipa_node_params *info = fbi->info;
2692 HOST_WIDE_INT offset;
2693 bool by_ref;
2695 if (SSA_NAME_IS_DEFAULT_DEF (target))
2697 tree var = SSA_NAME_VAR (target);
2698 int index = ipa_get_param_decl_index (info, var);
2699 if (index >= 0)
2700 ipa_note_param_call (fbi->node, index, call, false);
2701 return;
2704 int index;
2705 gimple *def = SSA_NAME_DEF_STMT (target);
2706 bool guaranteed_unmodified;
2707 if (gimple_assign_single_p (def)
2708 && ipa_load_from_parm_agg (fbi, info->descriptors, def,
2709 gimple_assign_rhs1 (def), &index, &offset,
2710 NULL, &by_ref, &guaranteed_unmodified))
2712 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
2713 call, false);
2714 cs->indirect_info->offset = offset;
2715 cs->indirect_info->agg_contents = 1;
2716 cs->indirect_info->by_ref = by_ref;
2717 cs->indirect_info->guaranteed_unmodified = guaranteed_unmodified;
2718 return;
2721 /* Now we need to try to match the complex pattern of calling a member
2722 pointer. */
2723 if (gimple_code (def) != GIMPLE_PHI
2724 || gimple_phi_num_args (def) != 2
2725 || !POINTER_TYPE_P (TREE_TYPE (target))
2726 || TREE_CODE (TREE_TYPE (TREE_TYPE (target))) != METHOD_TYPE)
2727 return;
2729 /* First, we need to check whether one of these is a load from a member
2730 pointer that is a parameter to this function. */
2731 tree n1 = PHI_ARG_DEF (def, 0);
2732 tree n2 = PHI_ARG_DEF (def, 1);
2733 if (!ipa_is_ssa_with_stmt_def (n1) || !ipa_is_ssa_with_stmt_def (n2))
2734 return;
2735 gimple *d1 = SSA_NAME_DEF_STMT (n1);
2736 gimple *d2 = SSA_NAME_DEF_STMT (n2);
2738 tree rec;
2739 basic_block bb, virt_bb;
2740 basic_block join = gimple_bb (def);
2741 if ((rec = ipa_get_stmt_member_ptr_load_param (d1, false, &offset)))
2743 if (ipa_get_stmt_member_ptr_load_param (d2, false, NULL))
2744 return;
2746 bb = EDGE_PRED (join, 0)->src;
2747 virt_bb = gimple_bb (d2);
2749 else if ((rec = ipa_get_stmt_member_ptr_load_param (d2, false, &offset)))
2751 bb = EDGE_PRED (join, 1)->src;
2752 virt_bb = gimple_bb (d1);
2754 else
2755 return;
2757 /* Second, we need to check that the basic blocks are laid out in the way
2758 corresponding to the pattern. */
2760 if (!single_pred_p (virt_bb) || !single_succ_p (virt_bb)
2761 || single_pred (virt_bb) != bb
2762 || single_succ (virt_bb) != join)
2763 return;
2765 /* Third, let's see that the branching is done depending on the least
2766 significant bit of the pfn. */
2768 gcond *branch = safe_dyn_cast <gcond *> (*gsi_last_bb (bb));
2769 if (!branch)
2770 return;
2772 if ((gimple_cond_code (branch) != NE_EXPR
2773 && gimple_cond_code (branch) != EQ_EXPR)
2774 || !integer_zerop (gimple_cond_rhs (branch)))
2775 return;
2777 tree cond = gimple_cond_lhs (branch);
2778 if (!ipa_is_ssa_with_stmt_def (cond))
2779 return;
2781 def = SSA_NAME_DEF_STMT (cond);
2782 if (!is_gimple_assign (def)
2783 || gimple_assign_rhs_code (def) != BIT_AND_EXPR
2784 || !integer_onep (gimple_assign_rhs2 (def)))
2785 return;
2787 cond = gimple_assign_rhs1 (def);
2788 if (!ipa_is_ssa_with_stmt_def (cond))
2789 return;
2791 def = SSA_NAME_DEF_STMT (cond);
2793 if (is_gimple_assign (def)
2794 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
2796 cond = gimple_assign_rhs1 (def);
2797 if (!ipa_is_ssa_with_stmt_def (cond))
2798 return;
2799 def = SSA_NAME_DEF_STMT (cond);
2802 tree rec2;
2803 rec2 = ipa_get_stmt_member_ptr_load_param (def,
2804 (TARGET_PTRMEMFUNC_VBIT_LOCATION
2805 == ptrmemfunc_vbit_in_delta),
2806 NULL);
2807 if (rec != rec2)
2808 return;
2810 index = ipa_get_param_decl_index (info, rec);
2811 if (index >= 0
2812 && parm_preserved_before_stmt_p (fbi, index, call, rec))
2814 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
2815 call, false);
2816 cs->indirect_info->offset = offset;
2817 cs->indirect_info->agg_contents = 1;
2818 cs->indirect_info->member_ptr = 1;
2819 cs->indirect_info->guaranteed_unmodified = 1;
2822 return;
2825 /* Analyze a CALL to an OBJ_TYPE_REF which is passed in TARGET and if the
2826 object referenced in the expression is a formal parameter of the caller
2827 FBI->node (described by FBI->info), create a call note for the
2828 statement. */
2830 static void
2831 ipa_analyze_virtual_call_uses (struct ipa_func_body_info *fbi,
2832 gcall *call, tree target)
2834 tree obj = OBJ_TYPE_REF_OBJECT (target);
2835 int index;
2836 HOST_WIDE_INT anc_offset;
2838 if (!flag_devirtualize)
2839 return;
2841 if (TREE_CODE (obj) != SSA_NAME)
2842 return;
2844 class ipa_node_params *info = fbi->info;
2845 if (SSA_NAME_IS_DEFAULT_DEF (obj))
2847 if (TREE_CODE (SSA_NAME_VAR (obj)) != PARM_DECL)
2848 return;
2850 anc_offset = 0;
2851 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (obj));
2852 gcc_assert (index >= 0);
2853 if (detect_type_change_ssa (fbi, obj, obj_type_ref_class (target),
2854 call))
2855 return;
2857 else
2859 gimple *stmt = SSA_NAME_DEF_STMT (obj);
2860 tree expr;
2862 expr = get_ancestor_addr_info (stmt, &obj, &anc_offset);
2863 if (!expr)
2864 return;
2865 index = ipa_get_param_decl_index (info,
2866 SSA_NAME_VAR (TREE_OPERAND (expr, 0)));
2867 gcc_assert (index >= 0);
2868 if (detect_type_change (fbi, obj, expr, obj_type_ref_class (target),
2869 call, anc_offset))
2870 return;
2873 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
2874 call, true);
2875 class cgraph_indirect_call_info *ii = cs->indirect_info;
2876 ii->offset = anc_offset;
2877 ii->otr_token = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target));
2878 ii->otr_type = obj_type_ref_class (target);
2879 ii->polymorphic = 1;
2882 /* Analyze a call statement CALL whether and how it utilizes formal parameters
2883 of the caller (described by INFO). PARMS_AINFO is a pointer to a vector
2884 containing intermediate information about each formal parameter. */
2886 static void
2887 ipa_analyze_call_uses (struct ipa_func_body_info *fbi, gcall *call)
2889 tree target = gimple_call_fn (call);
2891 if (!target
2892 || (TREE_CODE (target) != SSA_NAME
2893 && !virtual_method_call_p (target)))
2894 return;
2896 struct cgraph_edge *cs = fbi->node->get_edge (call);
2897 /* If we previously turned the call into a direct call, there is
2898 no need to analyze. */
2899 if (cs && !cs->indirect_unknown_callee)
2900 return;
2902 if (cs->indirect_info->polymorphic && flag_devirtualize)
2904 tree instance;
2905 tree target = gimple_call_fn (call);
2906 ipa_polymorphic_call_context context (current_function_decl,
2907 target, call, &instance);
2909 gcc_checking_assert (cs->indirect_info->otr_type
2910 == obj_type_ref_class (target));
2911 gcc_checking_assert (cs->indirect_info->otr_token
2912 == tree_to_shwi (OBJ_TYPE_REF_TOKEN (target)));
2914 cs->indirect_info->vptr_changed
2915 = !context.get_dynamic_type (instance,
2916 OBJ_TYPE_REF_OBJECT (target),
2917 obj_type_ref_class (target), call,
2918 &fbi->aa_walk_budget);
2919 cs->indirect_info->context = context;
2922 if (TREE_CODE (target) == SSA_NAME)
2923 ipa_analyze_indirect_call_uses (fbi, call, target);
2924 else if (virtual_method_call_p (target))
2925 ipa_analyze_virtual_call_uses (fbi, call, target);
2929 /* Analyze the call statement STMT with respect to formal parameters (described
2930 in INFO) of caller given by FBI->NODE. Currently it only checks whether
2931 formal parameters are called. */
2933 static void
2934 ipa_analyze_stmt_uses (struct ipa_func_body_info *fbi, gimple *stmt)
2936 if (is_gimple_call (stmt))
2937 ipa_analyze_call_uses (fbi, as_a <gcall *> (stmt));
2940 /* Callback of walk_stmt_load_store_addr_ops for the visit_load.
2941 If OP is a parameter declaration, mark it as used in the info structure
2942 passed in DATA. */
2944 static bool
2945 visit_ref_for_mod_analysis (gimple *, tree op, tree, void *data)
2947 class ipa_node_params *info = (class ipa_node_params *) data;
2949 op = get_base_address (op);
2950 if (op
2951 && TREE_CODE (op) == PARM_DECL)
2953 int index = ipa_get_param_decl_index (info, op);
2954 gcc_assert (index >= 0);
2955 ipa_set_param_used (info, index, true);
2958 return false;
2961 /* Scan the statements in BB and inspect the uses of formal parameters. Store
2962 the findings in various structures of the associated ipa_node_params
2963 structure, such as parameter flags, notes etc. FBI holds various data about
2964 the function being analyzed. */
2966 static void
2967 ipa_analyze_params_uses_in_bb (struct ipa_func_body_info *fbi, basic_block bb)
2969 gimple_stmt_iterator gsi;
2970 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2972 gimple *stmt = gsi_stmt (gsi);
2974 if (is_gimple_debug (stmt))
2975 continue;
2977 ipa_analyze_stmt_uses (fbi, stmt);
2978 walk_stmt_load_store_addr_ops (stmt, fbi->info,
2979 visit_ref_for_mod_analysis,
2980 visit_ref_for_mod_analysis,
2981 visit_ref_for_mod_analysis);
2983 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2984 walk_stmt_load_store_addr_ops (gsi_stmt (gsi), fbi->info,
2985 visit_ref_for_mod_analysis,
2986 visit_ref_for_mod_analysis,
2987 visit_ref_for_mod_analysis);
2990 /* Return true EXPR is a load from a dereference of SSA_NAME NAME. */
2992 static bool
2993 load_from_dereferenced_name (tree expr, tree name)
2995 tree base = get_base_address (expr);
2996 return (TREE_CODE (base) == MEM_REF
2997 && TREE_OPERAND (base, 0) == name);
3000 /* Calculate controlled uses of parameters of NODE. */
3002 static void
3003 ipa_analyze_controlled_uses (struct cgraph_node *node)
3005 ipa_node_params *info = ipa_node_params_sum->get (node);
3007 for (int i = 0; i < ipa_get_param_count (info); i++)
3009 tree parm = ipa_get_param (info, i);
3010 int call_uses = 0;
3011 bool load_dereferenced = false;
3013 /* For SSA regs see if parameter is used. For non-SSA we compute
3014 the flag during modification analysis. */
3015 if (is_gimple_reg (parm))
3017 tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl),
3018 parm);
3019 if (ddef && !has_zero_uses (ddef))
3021 imm_use_iterator imm_iter;
3022 gimple *stmt;
3024 ipa_set_param_used (info, i, true);
3025 FOR_EACH_IMM_USE_STMT (stmt, imm_iter, ddef)
3027 if (is_gimple_debug (stmt))
3028 continue;
3030 int all_stmt_uses = 0;
3031 use_operand_p use_p;
3032 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
3033 all_stmt_uses++;
3035 if (is_gimple_call (stmt))
3037 if (gimple_call_internal_p (stmt))
3039 call_uses = IPA_UNDESCRIBED_USE;
3040 break;
3042 int recognized_stmt_uses;
3043 if (gimple_call_fn (stmt) == ddef)
3044 recognized_stmt_uses = 1;
3045 else
3046 recognized_stmt_uses = 0;
3047 unsigned arg_count = gimple_call_num_args (stmt);
3048 for (unsigned i = 0; i < arg_count; i++)
3050 tree arg = gimple_call_arg (stmt, i);
3051 if (arg == ddef)
3052 recognized_stmt_uses++;
3053 else if (load_from_dereferenced_name (arg, ddef))
3055 load_dereferenced = true;
3056 recognized_stmt_uses++;
3060 if (recognized_stmt_uses != all_stmt_uses)
3062 call_uses = IPA_UNDESCRIBED_USE;
3063 break;
3065 if (call_uses >= 0)
3066 call_uses += all_stmt_uses;
3068 else if (gimple_assign_single_p (stmt))
3070 tree rhs = gimple_assign_rhs1 (stmt);
3071 if (all_stmt_uses != 1
3072 || !load_from_dereferenced_name (rhs, ddef))
3074 call_uses = IPA_UNDESCRIBED_USE;
3075 break;
3077 load_dereferenced = true;
3079 else
3081 call_uses = IPA_UNDESCRIBED_USE;
3082 break;
3086 else
3087 call_uses = 0;
3089 else
3090 call_uses = IPA_UNDESCRIBED_USE;
3091 ipa_set_controlled_uses (info, i, call_uses);
3092 ipa_set_param_load_dereferenced (info, i, load_dereferenced);
3096 /* Free stuff in BI. */
3098 static void
3099 free_ipa_bb_info (struct ipa_bb_info *bi)
3101 bi->cg_edges.release ();
3102 bi->param_aa_statuses.release ();
3105 /* Dominator walker driving the analysis. */
3107 class analysis_dom_walker : public dom_walker
3109 public:
3110 analysis_dom_walker (struct ipa_func_body_info *fbi)
3111 : dom_walker (CDI_DOMINATORS), m_fbi (fbi) {}
3113 edge before_dom_children (basic_block) final override;
3115 private:
3116 struct ipa_func_body_info *m_fbi;
3119 edge
3120 analysis_dom_walker::before_dom_children (basic_block bb)
3122 ipa_analyze_params_uses_in_bb (m_fbi, bb);
3123 ipa_compute_jump_functions_for_bb (m_fbi, bb);
3124 return NULL;
3127 /* Release body info FBI. */
3129 void
3130 ipa_release_body_info (struct ipa_func_body_info *fbi)
3132 int i;
3133 struct ipa_bb_info *bi;
3135 FOR_EACH_VEC_ELT (fbi->bb_infos, i, bi)
3136 free_ipa_bb_info (bi);
3137 fbi->bb_infos.release ();
3140 /* Initialize the array describing properties of formal parameters
3141 of NODE, analyze their uses and compute jump functions associated
3142 with actual arguments of calls from within NODE. */
3144 void
3145 ipa_analyze_node (struct cgraph_node *node)
3147 struct ipa_func_body_info fbi;
3148 class ipa_node_params *info;
3150 ipa_check_create_node_params ();
3151 ipa_check_create_edge_args ();
3152 info = ipa_node_params_sum->get_create (node);
3154 if (info->analysis_done)
3155 return;
3156 info->analysis_done = 1;
3158 if (ipa_func_spec_opts_forbid_analysis_p (node)
3159 || (count_formal_params (node->decl)
3160 >= (1 << IPA_PROP_ARG_INDEX_LIMIT_BITS)))
3162 gcc_assert (!ipa_get_param_count (info));
3163 return;
3166 struct function *func = DECL_STRUCT_FUNCTION (node->decl);
3167 push_cfun (func);
3168 calculate_dominance_info (CDI_DOMINATORS);
3169 ipa_initialize_node_params (node);
3170 ipa_analyze_controlled_uses (node);
3172 fbi.node = node;
3173 fbi.info = info;
3174 fbi.bb_infos = vNULL;
3175 fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
3176 fbi.param_count = ipa_get_param_count (info);
3177 fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps);
3179 for (struct cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
3181 ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
3182 bi->cg_edges.safe_push (cs);
3185 for (struct cgraph_edge *cs = node->indirect_calls; cs; cs = cs->next_callee)
3187 ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
3188 bi->cg_edges.safe_push (cs);
3191 analysis_dom_walker (&fbi).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
3193 ipa_release_body_info (&fbi);
3194 free_dominance_info (CDI_DOMINATORS);
3195 pop_cfun ();
3198 /* Update the jump functions associated with call graph edge E when the call
3199 graph edge CS is being inlined, assuming that E->caller is already (possibly
3200 indirectly) inlined into CS->callee and that E has not been inlined. */
3202 static void
3203 update_jump_functions_after_inlining (struct cgraph_edge *cs,
3204 struct cgraph_edge *e)
3206 ipa_edge_args *top = ipa_edge_args_sum->get (cs);
3207 ipa_edge_args *args = ipa_edge_args_sum->get (e);
3208 if (!args)
3209 return;
3210 int count = ipa_get_cs_argument_count (args);
3211 int i;
3213 for (i = 0; i < count; i++)
3215 struct ipa_jump_func *dst = ipa_get_ith_jump_func (args, i);
3216 class ipa_polymorphic_call_context *dst_ctx
3217 = ipa_get_ith_polymorhic_call_context (args, i);
3219 if (dst->agg.items)
3221 struct ipa_agg_jf_item *item;
3222 int j;
3224 FOR_EACH_VEC_ELT (*dst->agg.items, j, item)
3226 int dst_fid;
3227 struct ipa_jump_func *src;
3229 if (item->jftype != IPA_JF_PASS_THROUGH
3230 && item->jftype != IPA_JF_LOAD_AGG)
3231 continue;
3233 dst_fid = item->value.pass_through.formal_id;
3234 if (!top || dst_fid >= ipa_get_cs_argument_count (top))
3236 item->jftype = IPA_JF_UNKNOWN;
3237 continue;
3240 item->value.pass_through.formal_id = -1;
3241 src = ipa_get_ith_jump_func (top, dst_fid);
3242 if (src->type == IPA_JF_CONST)
3244 if (item->jftype == IPA_JF_PASS_THROUGH
3245 && item->value.pass_through.operation == NOP_EXPR)
3247 item->jftype = IPA_JF_CONST;
3248 item->value.constant = src->value.constant.value;
3249 continue;
3252 else if (src->type == IPA_JF_PASS_THROUGH
3253 && src->value.pass_through.operation == NOP_EXPR)
3255 if (item->jftype == IPA_JF_PASS_THROUGH
3256 || !item->value.load_agg.by_ref
3257 || src->value.pass_through.agg_preserved)
3258 item->value.pass_through.formal_id
3259 = src->value.pass_through.formal_id;
3261 else if (src->type == IPA_JF_ANCESTOR)
3263 if (item->jftype == IPA_JF_PASS_THROUGH)
3265 if (!src->value.ancestor.offset)
3266 item->value.pass_through.formal_id
3267 = src->value.ancestor.formal_id;
3269 else if (src->value.ancestor.agg_preserved)
3271 gcc_checking_assert (item->value.load_agg.by_ref);
3273 item->value.pass_through.formal_id
3274 = src->value.ancestor.formal_id;
3275 item->value.load_agg.offset
3276 += src->value.ancestor.offset;
3280 if (item->value.pass_through.formal_id < 0)
3281 item->jftype = IPA_JF_UNKNOWN;
3285 if (!top)
3287 ipa_set_jf_unknown (dst);
3288 continue;
3291 if (dst->type == IPA_JF_ANCESTOR)
3293 struct ipa_jump_func *src;
3294 int dst_fid = dst->value.ancestor.formal_id;
3295 class ipa_polymorphic_call_context *src_ctx
3296 = ipa_get_ith_polymorhic_call_context (top, dst_fid);
3298 /* Variable number of arguments can cause havoc if we try to access
3299 one that does not exist in the inlined edge. So make sure we
3300 don't. */
3301 if (dst_fid >= ipa_get_cs_argument_count (top))
3303 ipa_set_jf_unknown (dst);
3304 continue;
3307 src = ipa_get_ith_jump_func (top, dst_fid);
3309 if (src_ctx && !src_ctx->useless_p ())
3311 class ipa_polymorphic_call_context ctx = *src_ctx;
3313 /* TODO: Make type preserved safe WRT contexts. */
3314 if (!ipa_get_jf_ancestor_type_preserved (dst))
3315 ctx.possible_dynamic_type_change (e->in_polymorphic_cdtor);
3316 ctx.offset_by (dst->value.ancestor.offset);
3317 if (!ctx.useless_p ())
3319 if (!dst_ctx)
3321 vec_safe_grow_cleared (args->polymorphic_call_contexts,
3322 count, true);
3323 dst_ctx = ipa_get_ith_polymorhic_call_context (args, i);
3326 dst_ctx->combine_with (ctx);
3330 /* Parameter and argument in ancestor jump function must be pointer
3331 type, which means access to aggregate must be by-reference. */
3332 gcc_assert (!src->agg.items || src->agg.by_ref);
3334 if (src->agg.items && dst->value.ancestor.agg_preserved)
3336 struct ipa_agg_jf_item *item;
3337 int j;
3339 /* Currently we do not produce clobber aggregate jump functions,
3340 replace with merging when we do. */
3341 gcc_assert (!dst->agg.items);
3343 dst->agg.items = vec_safe_copy (src->agg.items);
3344 dst->agg.by_ref = src->agg.by_ref;
3345 FOR_EACH_VEC_SAFE_ELT (dst->agg.items, j, item)
3346 item->offset -= dst->value.ancestor.offset;
3349 if (src->type == IPA_JF_PASS_THROUGH
3350 && src->value.pass_through.operation == NOP_EXPR)
3352 dst->value.ancestor.formal_id = src->value.pass_through.formal_id;
3353 dst->value.ancestor.agg_preserved &=
3354 src->value.pass_through.agg_preserved;
3356 else if (src->type == IPA_JF_ANCESTOR)
3358 dst->value.ancestor.formal_id = src->value.ancestor.formal_id;
3359 dst->value.ancestor.offset += src->value.ancestor.offset;
3360 dst->value.ancestor.agg_preserved &=
3361 src->value.ancestor.agg_preserved;
3362 dst->value.ancestor.keep_null |= src->value.ancestor.keep_null;
3364 else
3365 ipa_set_jf_unknown (dst);
3367 else if (dst->type == IPA_JF_PASS_THROUGH)
3369 struct ipa_jump_func *src;
3370 /* We must check range due to calls with variable number of arguments
3371 and we cannot combine jump functions with operations. */
3372 if (dst->value.pass_through.operation == NOP_EXPR
3373 && (top && dst->value.pass_through.formal_id
3374 < ipa_get_cs_argument_count (top)))
3376 int dst_fid = dst->value.pass_through.formal_id;
3377 src = ipa_get_ith_jump_func (top, dst_fid);
3378 bool dst_agg_p = ipa_get_jf_pass_through_agg_preserved (dst);
3379 class ipa_polymorphic_call_context *src_ctx
3380 = ipa_get_ith_polymorhic_call_context (top, dst_fid);
3382 if (src_ctx && !src_ctx->useless_p ())
3384 class ipa_polymorphic_call_context ctx = *src_ctx;
3386 /* TODO: Make type preserved safe WRT contexts. */
3387 if (!ipa_get_jf_pass_through_type_preserved (dst))
3388 ctx.possible_dynamic_type_change (e->in_polymorphic_cdtor);
3389 if (!ctx.useless_p ())
3391 if (!dst_ctx)
3393 vec_safe_grow_cleared (args->polymorphic_call_contexts,
3394 count, true);
3395 dst_ctx = ipa_get_ith_polymorhic_call_context (args, i);
3397 dst_ctx->combine_with (ctx);
3400 switch (src->type)
3402 case IPA_JF_UNKNOWN:
3403 ipa_set_jf_unknown (dst);
3404 break;
3405 case IPA_JF_CONST:
3407 bool rd = ipa_get_jf_pass_through_refdesc_decremented (dst);
3408 ipa_set_jf_cst_copy (dst, src);
3409 if (rd)
3410 ipa_zap_jf_refdesc (dst);
3413 break;
3415 case IPA_JF_PASS_THROUGH:
3417 int formal_id = ipa_get_jf_pass_through_formal_id (src);
3418 enum tree_code operation;
3419 operation = ipa_get_jf_pass_through_operation (src);
3421 if (operation == NOP_EXPR)
3423 bool agg_p;
3424 agg_p = dst_agg_p
3425 && ipa_get_jf_pass_through_agg_preserved (src);
3426 ipa_set_jf_simple_pass_through (dst, formal_id, agg_p);
3428 else if (TREE_CODE_CLASS (operation) == tcc_unary)
3429 ipa_set_jf_unary_pass_through (dst, formal_id, operation);
3430 else
3432 tree operand = ipa_get_jf_pass_through_operand (src);
3433 ipa_set_jf_arith_pass_through (dst, formal_id, operand,
3434 operation);
3436 break;
3438 case IPA_JF_ANCESTOR:
3440 bool agg_p;
3441 agg_p = dst_agg_p
3442 && ipa_get_jf_ancestor_agg_preserved (src);
3443 ipa_set_ancestor_jf (dst,
3444 ipa_get_jf_ancestor_offset (src),
3445 ipa_get_jf_ancestor_formal_id (src),
3446 agg_p,
3447 ipa_get_jf_ancestor_keep_null (src));
3448 break;
3450 default:
3451 gcc_unreachable ();
3454 if (src->agg.items
3455 && (dst_agg_p || !src->agg.by_ref))
3457 /* Currently we do not produce clobber aggregate jump
3458 functions, replace with merging when we do. */
3459 gcc_assert (!dst->agg.items);
3461 dst->agg.by_ref = src->agg.by_ref;
3462 dst->agg.items = vec_safe_copy (src->agg.items);
3465 else
3466 ipa_set_jf_unknown (dst);
3471 /* If TARGET is an addr_expr of a function declaration, make it the
3472 (SPECULATIVE)destination of an indirect edge IE and return the edge.
3473 Otherwise, return NULL. */
3475 struct cgraph_edge *
3476 ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
3477 bool speculative)
3479 struct cgraph_node *callee;
3480 bool unreachable = false;
3482 if (TREE_CODE (target) == ADDR_EXPR)
3483 target = TREE_OPERAND (target, 0);
3484 if (TREE_CODE (target) != FUNCTION_DECL)
3486 target = canonicalize_constructor_val (target, NULL);
3487 if (!target || TREE_CODE (target) != FUNCTION_DECL)
3489 /* Member pointer call that goes through a VMT lookup. */
3490 if (ie->indirect_info->member_ptr
3491 /* Or if target is not an invariant expression and we do not
3492 know if it will evaulate to function at runtime.
3493 This can happen when folding through &VAR, where &VAR
3494 is IP invariant, but VAR itself is not.
3496 TODO: Revisit this when GCC 5 is branched. It seems that
3497 member_ptr check is not needed and that we may try to fold
3498 the expression and see if VAR is readonly. */
3499 || !is_gimple_ip_invariant (target))
3501 if (dump_enabled_p ())
3503 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
3504 "discovered direct call non-invariant %s\n",
3505 ie->caller->dump_name ());
3507 return NULL;
3511 if (dump_enabled_p ())
3513 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
3514 "discovered direct call to non-function in %s, "
3515 "making it __builtin_unreachable\n",
3516 ie->caller->dump_name ());
3519 target = builtin_decl_unreachable ();
3520 callee = cgraph_node::get_create (target);
3521 unreachable = true;
3523 else
3524 callee = cgraph_node::get (target);
3526 else
3527 callee = cgraph_node::get (target);
3529 /* Because may-edges are not explicitely represented and vtable may be external,
3530 we may create the first reference to the object in the unit. */
3531 if (!callee || callee->inlined_to)
3534 /* We are better to ensure we can refer to it.
3535 In the case of static functions we are out of luck, since we already
3536 removed its body. In the case of public functions we may or may
3537 not introduce the reference. */
3538 if (!canonicalize_constructor_val (target, NULL)
3539 || !TREE_PUBLIC (target))
3541 if (dump_file)
3542 fprintf (dump_file, "ipa-prop: Discovered call to a known target "
3543 "(%s -> %s) but cannot refer to it. Giving up.\n",
3544 ie->caller->dump_name (),
3545 ie->callee->dump_name ());
3546 return NULL;
3548 callee = cgraph_node::get_create (target);
3551 /* If the edge is already speculated. */
3552 if (speculative && ie->speculative)
3554 if (dump_file)
3556 cgraph_edge *e2 = ie->speculative_call_for_target (callee);
3557 if (!e2)
3559 if (dump_file)
3560 fprintf (dump_file, "ipa-prop: Discovered call to a "
3561 "speculative target (%s -> %s) but the call is "
3562 "already speculated to different target. "
3563 "Giving up.\n",
3564 ie->caller->dump_name (), callee->dump_name ());
3566 else
3568 if (dump_file)
3569 fprintf (dump_file,
3570 "ipa-prop: Discovered call to a speculative target "
3571 "(%s -> %s) this agree with previous speculation.\n",
3572 ie->caller->dump_name (), callee->dump_name ());
3575 return NULL;
3578 if (!dbg_cnt (devirt))
3579 return NULL;
3581 ipa_check_create_node_params ();
3583 /* We cannot make edges to inline clones. It is bug that someone removed
3584 the cgraph node too early. */
3585 gcc_assert (!callee->inlined_to);
3587 if (dump_file && !unreachable)
3589 fprintf (dump_file, "ipa-prop: Discovered %s call to a %s target "
3590 "(%s -> %s), for stmt ",
3591 ie->indirect_info->polymorphic ? "a virtual" : "an indirect",
3592 speculative ? "speculative" : "known",
3593 ie->caller->dump_name (),
3594 callee->dump_name ());
3595 if (ie->call_stmt)
3596 print_gimple_stmt (dump_file, ie->call_stmt, 2, TDF_SLIM);
3597 else
3598 fprintf (dump_file, "with uid %i\n", ie->lto_stmt_uid);
3600 if (dump_enabled_p ())
3602 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
3603 "converting indirect call in %s to direct call to %s\n",
3604 ie->caller->dump_name (), callee->dump_name ());
3606 if (!speculative)
3608 struct cgraph_edge *orig = ie;
3609 ie = cgraph_edge::make_direct (ie, callee);
3610 /* If we resolved speculative edge the cost is already up to date
3611 for direct call (adjusted by inline_edge_duplication_hook). */
3612 if (ie == orig)
3614 ipa_call_summary *es = ipa_call_summaries->get (ie);
3615 es->call_stmt_size -= (eni_size_weights.indirect_call_cost
3616 - eni_size_weights.call_cost);
3617 es->call_stmt_time -= (eni_time_weights.indirect_call_cost
3618 - eni_time_weights.call_cost);
3621 else
3623 if (!callee->can_be_discarded_p ())
3625 cgraph_node *alias;
3626 alias = dyn_cast<cgraph_node *> (callee->noninterposable_alias ());
3627 if (alias)
3628 callee = alias;
3630 /* make_speculative will update ie's cost to direct call cost. */
3631 ie = ie->make_speculative
3632 (callee, ie->count.apply_scale (8, 10));
3635 return ie;
3638 /* Attempt to locate an interprocedural constant at a given REQ_OFFSET in
3639 CONSTRUCTOR and return it. Return NULL if the search fails for some
3640 reason. */
3642 static tree
3643 find_constructor_constant_at_offset (tree constructor, HOST_WIDE_INT req_offset)
3645 tree type = TREE_TYPE (constructor);
3646 if (TREE_CODE (type) != ARRAY_TYPE
3647 && TREE_CODE (type) != RECORD_TYPE)
3648 return NULL;
3650 unsigned ix;
3651 tree index, val;
3652 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (constructor), ix, index, val)
3654 HOST_WIDE_INT elt_offset;
3655 if (TREE_CODE (type) == ARRAY_TYPE)
3657 offset_int off;
3658 tree unit_size = TYPE_SIZE_UNIT (TREE_TYPE (type));
3659 gcc_assert (TREE_CODE (unit_size) == INTEGER_CST);
3661 if (index)
3663 if (TREE_CODE (index) == RANGE_EXPR)
3664 off = wi::to_offset (TREE_OPERAND (index, 0));
3665 else
3666 off = wi::to_offset (index);
3667 if (TYPE_DOMAIN (type) && TYPE_MIN_VALUE (TYPE_DOMAIN (type)))
3669 tree low_bound = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
3670 gcc_assert (TREE_CODE (unit_size) == INTEGER_CST);
3671 off = wi::sext (off - wi::to_offset (low_bound),
3672 TYPE_PRECISION (TREE_TYPE (index)));
3674 off *= wi::to_offset (unit_size);
3675 /* ??? Handle more than just the first index of a
3676 RANGE_EXPR. */
3678 else
3679 off = wi::to_offset (unit_size) * ix;
3681 off = wi::lshift (off, LOG2_BITS_PER_UNIT);
3682 if (!wi::fits_shwi_p (off) || wi::neg_p (off))
3683 continue;
3684 elt_offset = off.to_shwi ();
3686 else if (TREE_CODE (type) == RECORD_TYPE)
3688 gcc_checking_assert (index && TREE_CODE (index) == FIELD_DECL);
3689 if (DECL_BIT_FIELD (index))
3690 continue;
3691 elt_offset = int_bit_position (index);
3693 else
3694 gcc_unreachable ();
3696 if (elt_offset > req_offset)
3697 return NULL;
3699 if (TREE_CODE (val) == CONSTRUCTOR)
3700 return find_constructor_constant_at_offset (val,
3701 req_offset - elt_offset);
3703 if (elt_offset == req_offset
3704 && is_gimple_reg_type (TREE_TYPE (val))
3705 && is_gimple_ip_invariant (val))
3706 return val;
3708 return NULL;
3711 /* Check whether SCALAR could be used to look up an aggregate interprocedural
3712 invariant from a static constructor and if so, return it. Otherwise return
3713 NULL. */
3715 tree
3716 ipa_find_agg_cst_from_init (tree scalar, HOST_WIDE_INT offset, bool by_ref)
3718 if (by_ref)
3720 if (TREE_CODE (scalar) != ADDR_EXPR)
3721 return NULL;
3722 scalar = TREE_OPERAND (scalar, 0);
3725 if (!VAR_P (scalar)
3726 || !is_global_var (scalar)
3727 || !TREE_READONLY (scalar)
3728 || !DECL_INITIAL (scalar)
3729 || TREE_CODE (DECL_INITIAL (scalar)) != CONSTRUCTOR)
3730 return NULL;
3732 return find_constructor_constant_at_offset (DECL_INITIAL (scalar), offset);
3735 /* Retrieve value from AGG_JFUNC for the given OFFSET or return NULL if there
3736 is none. BY_REF specifies whether the value has to be passed by reference
3737 or by value. */
3739 static tree
3740 ipa_find_agg_cst_from_jfunc_items (struct ipa_agg_jump_function *agg_jfunc,
3741 ipa_node_params *src_info,
3742 cgraph_node *src_node,
3743 HOST_WIDE_INT offset, bool by_ref)
3745 if (by_ref != agg_jfunc->by_ref)
3746 return NULL_TREE;
3748 for (const ipa_agg_jf_item &item : agg_jfunc->items)
3749 if (item.offset == offset)
3750 return ipa_agg_value_from_jfunc (src_info, src_node, &item);
3752 return NULL_TREE;
3755 /* Remove a reference to SYMBOL from the list of references of a node given by
3756 reference description RDESC. Return true if the reference has been
3757 successfully found and removed. */
3759 static bool
3760 remove_described_reference (symtab_node *symbol, struct ipa_cst_ref_desc *rdesc)
3762 struct ipa_ref *to_del;
3763 struct cgraph_edge *origin;
3765 origin = rdesc->cs;
3766 if (!origin)
3767 return false;
3768 to_del = origin->caller->find_reference (symbol, origin->call_stmt,
3769 origin->lto_stmt_uid, IPA_REF_ADDR);
3770 if (!to_del)
3771 return false;
3773 to_del->remove_reference ();
3774 if (dump_file)
3775 fprintf (dump_file, "ipa-prop: Removed a reference from %s to %s.\n",
3776 origin->caller->dump_name (), symbol->dump_name ());
3777 return true;
3780 /* If JFUNC has a reference description with refcount different from
3781 IPA_UNDESCRIBED_USE, return the reference description, otherwise return
3782 NULL. JFUNC must be a constant jump function. */
3784 static struct ipa_cst_ref_desc *
3785 jfunc_rdesc_usable (struct ipa_jump_func *jfunc)
3787 struct ipa_cst_ref_desc *rdesc = ipa_get_jf_constant_rdesc (jfunc);
3788 if (rdesc && rdesc->refcount != IPA_UNDESCRIBED_USE)
3789 return rdesc;
3790 else
3791 return NULL;
3794 /* If the value of constant jump function JFUNC is an address of a function
3795 declaration, return the associated call graph node. Otherwise return
3796 NULL. */
3798 static symtab_node *
3799 symtab_node_for_jfunc (struct ipa_jump_func *jfunc)
3801 gcc_checking_assert (jfunc->type == IPA_JF_CONST);
3802 tree cst = ipa_get_jf_constant (jfunc);
3803 if (TREE_CODE (cst) != ADDR_EXPR
3804 || (TREE_CODE (TREE_OPERAND (cst, 0)) != FUNCTION_DECL
3805 && TREE_CODE (TREE_OPERAND (cst, 0)) != VAR_DECL))
3806 return NULL;
3808 return symtab_node::get (TREE_OPERAND (cst, 0));
3812 /* If JFUNC is a constant jump function with a usable rdesc, decrement its
3813 refcount and if it hits zero, remove reference to SYMBOL from the caller of
3814 the edge specified in the rdesc. Return false if either the symbol or the
3815 reference could not be found, otherwise return true. */
3817 static bool
3818 try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc)
3820 struct ipa_cst_ref_desc *rdesc;
3821 if (jfunc->type == IPA_JF_CONST
3822 && (rdesc = jfunc_rdesc_usable (jfunc))
3823 && --rdesc->refcount == 0)
3825 symtab_node *symbol = symtab_node_for_jfunc (jfunc);
3826 if (!symbol)
3827 return false;
3829 return remove_described_reference (symbol, rdesc);
3831 return true;
3834 /* Try to find a destination for indirect edge IE that corresponds to a simple
3835 call or a call of a member function pointer and where the destination is a
3836 pointer formal parameter described by jump function JFUNC. TARGET_TYPE is
3837 the type of the parameter to which the result of JFUNC is passed. If it can
3838 be determined, return the newly direct edge, otherwise return NULL.
3839 NEW_ROOT and NEW_ROOT_INFO is the node and its info that JFUNC lattices are
3840 relative to. */
3842 static struct cgraph_edge *
3843 try_make_edge_direct_simple_call (struct cgraph_edge *ie,
3844 struct ipa_jump_func *jfunc, tree target_type,
3845 struct cgraph_node *new_root,
3846 class ipa_node_params *new_root_info)
3848 struct cgraph_edge *cs;
3849 tree target = NULL_TREE;
3850 bool agg_contents = ie->indirect_info->agg_contents;
3851 tree scalar = ipa_value_from_jfunc (new_root_info, jfunc, target_type);
3852 if (agg_contents)
3854 if (scalar)
3855 target = ipa_find_agg_cst_from_init (scalar, ie->indirect_info->offset,
3856 ie->indirect_info->by_ref);
3857 if (!target && ie->indirect_info->guaranteed_unmodified)
3858 target = ipa_find_agg_cst_from_jfunc_items (&jfunc->agg, new_root_info,
3859 new_root,
3860 ie->indirect_info->offset,
3861 ie->indirect_info->by_ref);
3863 else
3864 target = scalar;
3865 if (!target)
3866 return NULL;
3867 cs = ipa_make_edge_direct_to_target (ie, target);
3869 if (cs && !agg_contents)
3871 bool ok;
3872 gcc_checking_assert (cs->callee
3873 && (cs != ie
3874 || jfunc->type != IPA_JF_CONST
3875 || !symtab_node_for_jfunc (jfunc)
3876 || cs->callee == symtab_node_for_jfunc (jfunc)));
3877 ok = try_decrement_rdesc_refcount (jfunc);
3878 gcc_checking_assert (ok);
3881 return cs;
3884 /* Return the target to be used in cases of impossible devirtualization. IE
3885 and target (the latter can be NULL) are dumped when dumping is enabled. */
3887 tree
3888 ipa_impossible_devirt_target (struct cgraph_edge *ie, tree target)
3890 if (dump_file)
3892 if (target)
3893 fprintf (dump_file,
3894 "Type inconsistent devirtualization: %s->%s\n",
3895 ie->caller->dump_name (),
3896 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (target)));
3897 else
3898 fprintf (dump_file,
3899 "No devirtualization target in %s\n",
3900 ie->caller->dump_name ());
3902 tree new_target = builtin_decl_unreachable ();
3903 cgraph_node::get_create (new_target);
3904 return new_target;
3907 /* Try to find a destination for indirect edge IE that corresponds to a virtual
3908 call based on a formal parameter which is described by jump function JFUNC
3909 and if it can be determined, make it direct and return the direct edge.
3910 Otherwise, return NULL. CTX describes the polymorphic context that the
3911 parameter the call is based on brings along with it. NEW_ROOT and
3912 NEW_ROOT_INFO is the node and its info that JFUNC lattices are relative
3913 to. */
3915 static struct cgraph_edge *
3916 try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
3917 struct ipa_jump_func *jfunc,
3918 class ipa_polymorphic_call_context ctx,
3919 struct cgraph_node *new_root,
3920 class ipa_node_params *new_root_info)
3922 tree target = NULL;
3923 bool speculative = false;
3925 if (!opt_for_fn (ie->caller->decl, flag_devirtualize))
3926 return NULL;
3928 gcc_assert (!ie->indirect_info->by_ref);
3930 /* Try to do lookup via known virtual table pointer value. */
3931 if (!ie->indirect_info->vptr_changed
3932 || opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively))
3934 tree vtable;
3935 unsigned HOST_WIDE_INT offset;
3936 tree t = NULL_TREE;
3937 if (jfunc->type == IPA_JF_CONST)
3938 t = ipa_find_agg_cst_from_init (ipa_get_jf_constant (jfunc),
3939 ie->indirect_info->offset, true);
3940 if (!t)
3941 t = ipa_find_agg_cst_from_jfunc_items (&jfunc->agg, new_root_info,
3942 new_root,
3943 ie->indirect_info->offset, true);
3944 if (t && vtable_pointer_value_to_vtable (t, &vtable, &offset))
3946 bool can_refer;
3947 t = gimple_get_virt_method_for_vtable (ie->indirect_info->otr_token,
3948 vtable, offset, &can_refer);
3949 if (can_refer)
3951 if (!t
3952 || fndecl_built_in_p (t, BUILT_IN_UNREACHABLE,
3953 BUILT_IN_UNREACHABLE_TRAP)
3954 || !possible_polymorphic_call_target_p
3955 (ie, cgraph_node::get (t)))
3957 /* Do not speculate builtin_unreachable, it is stupid! */
3958 if (!ie->indirect_info->vptr_changed)
3959 target = ipa_impossible_devirt_target (ie, target);
3960 else
3961 target = NULL;
3963 else
3965 target = t;
3966 speculative = ie->indirect_info->vptr_changed;
3972 ipa_polymorphic_call_context ie_context (ie);
3973 vec <cgraph_node *>targets;
3974 bool final;
3976 ctx.offset_by (ie->indirect_info->offset);
3977 if (ie->indirect_info->vptr_changed)
3978 ctx.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
3979 ie->indirect_info->otr_type);
3980 ctx.combine_with (ie_context, ie->indirect_info->otr_type);
3981 targets = possible_polymorphic_call_targets
3982 (ie->indirect_info->otr_type,
3983 ie->indirect_info->otr_token,
3984 ctx, &final);
3985 if (final && targets.length () <= 1)
3987 speculative = false;
3988 if (targets.length () == 1)
3989 target = targets[0]->decl;
3990 else
3991 target = ipa_impossible_devirt_target (ie, NULL_TREE);
3993 else if (!target && opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively)
3994 && !ie->speculative && ie->maybe_hot_p ())
3996 cgraph_node *n;
3997 n = try_speculative_devirtualization (ie->indirect_info->otr_type,
3998 ie->indirect_info->otr_token,
3999 ie->indirect_info->context);
4000 if (n)
4002 target = n->decl;
4003 speculative = true;
4007 if (target)
4009 if (!possible_polymorphic_call_target_p
4010 (ie, cgraph_node::get_create (target)))
4012 if (speculative)
4013 return NULL;
4014 target = ipa_impossible_devirt_target (ie, target);
4016 return ipa_make_edge_direct_to_target (ie, target, speculative);
4018 else
4019 return NULL;
4022 /* Update the param called notes associated with NODE when CS is being inlined,
4023 assuming NODE is (potentially indirectly) inlined into CS->callee.
4024 Moreover, if the callee is discovered to be constant, create a new cgraph
4025 edge for it. Newly discovered indirect edges will be added to *NEW_EDGES,
4026 unless NEW_EDGES is NULL. Return true iff a new edge(s) were created. */
4028 static bool
4029 update_indirect_edges_after_inlining (struct cgraph_edge *cs,
4030 struct cgraph_node *node,
4031 vec<cgraph_edge *> *new_edges)
4033 class ipa_edge_args *top;
4034 struct cgraph_edge *ie, *next_ie, *new_direct_edge;
4035 struct cgraph_node *new_root;
4036 class ipa_node_params *new_root_info, *inlined_node_info;
4037 bool res = false;
4039 ipa_check_create_edge_args ();
4040 top = ipa_edge_args_sum->get (cs);
4041 new_root = cs->caller->inlined_to
4042 ? cs->caller->inlined_to : cs->caller;
4043 new_root_info = ipa_node_params_sum->get (new_root);
4044 inlined_node_info = ipa_node_params_sum->get (cs->callee->function_symbol ());
4046 for (ie = node->indirect_calls; ie; ie = next_ie)
4048 class cgraph_indirect_call_info *ici = ie->indirect_info;
4049 struct ipa_jump_func *jfunc;
4050 int param_index;
4052 next_ie = ie->next_callee;
4054 if (ici->param_index == -1)
4055 continue;
4057 /* We must check range due to calls with variable number of arguments: */
4058 if (!top || ici->param_index >= ipa_get_cs_argument_count (top))
4060 ici->param_index = -1;
4061 continue;
4064 param_index = ici->param_index;
4065 jfunc = ipa_get_ith_jump_func (top, param_index);
4067 auto_vec<cgraph_node *, 4> spec_targets;
4068 if (ie->speculative)
4069 for (cgraph_edge *direct = ie->first_speculative_call_target ();
4070 direct;
4071 direct = direct->next_speculative_call_target ())
4072 spec_targets.safe_push (direct->callee);
4074 if (!opt_for_fn (node->decl, flag_indirect_inlining))
4075 new_direct_edge = NULL;
4076 else if (ici->polymorphic)
4078 ipa_polymorphic_call_context ctx;
4079 ctx = ipa_context_from_jfunc (new_root_info, cs, param_index, jfunc);
4080 new_direct_edge = try_make_edge_direct_virtual_call (ie, jfunc, ctx,
4081 new_root,
4082 new_root_info);
4084 else
4086 tree target_type = ipa_get_type (inlined_node_info, param_index);
4087 new_direct_edge = try_make_edge_direct_simple_call (ie, jfunc,
4088 target_type,
4089 new_root,
4090 new_root_info);
4093 /* If speculation was removed, then we need to do nothing. */
4094 if (new_direct_edge && new_direct_edge != ie
4095 && spec_targets.contains (new_direct_edge->callee))
4097 new_direct_edge->indirect_inlining_edge = 1;
4098 res = true;
4099 if (!new_direct_edge->speculative)
4100 continue;
4102 else if (new_direct_edge)
4104 new_direct_edge->indirect_inlining_edge = 1;
4105 if (new_edges)
4107 new_edges->safe_push (new_direct_edge);
4108 res = true;
4110 /* If speculative edge was introduced we still need to update
4111 call info of the indirect edge. */
4112 if (!new_direct_edge->speculative)
4113 continue;
4115 if (jfunc->type == IPA_JF_PASS_THROUGH
4116 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
4118 if (ici->agg_contents
4119 && !ipa_get_jf_pass_through_agg_preserved (jfunc)
4120 && !ici->polymorphic)
4121 ici->param_index = -1;
4122 else
4124 ici->param_index = ipa_get_jf_pass_through_formal_id (jfunc);
4125 if (ici->polymorphic
4126 && !ipa_get_jf_pass_through_type_preserved (jfunc))
4127 ici->vptr_changed = true;
4128 ipa_set_param_used_by_indirect_call (new_root_info,
4129 ici->param_index, true);
4130 if (ici->polymorphic)
4131 ipa_set_param_used_by_polymorphic_call (new_root_info,
4132 ici->param_index, true);
4135 else if (jfunc->type == IPA_JF_ANCESTOR)
4137 if (ici->agg_contents
4138 && !ipa_get_jf_ancestor_agg_preserved (jfunc)
4139 && !ici->polymorphic)
4140 ici->param_index = -1;
4141 else
4143 ici->param_index = ipa_get_jf_ancestor_formal_id (jfunc);
4144 ici->offset += ipa_get_jf_ancestor_offset (jfunc);
4145 if (ici->polymorphic
4146 && !ipa_get_jf_ancestor_type_preserved (jfunc))
4147 ici->vptr_changed = true;
4148 ipa_set_param_used_by_indirect_call (new_root_info,
4149 ici->param_index, true);
4150 if (ici->polymorphic)
4151 ipa_set_param_used_by_polymorphic_call (new_root_info,
4152 ici->param_index, true);
4155 else
4156 /* Either we can find a destination for this edge now or never. */
4157 ici->param_index = -1;
4160 return res;
4163 /* Recursively traverse subtree of NODE (including node) made of inlined
4164 cgraph_edges when CS has been inlined and invoke
4165 update_indirect_edges_after_inlining on all nodes and
4166 update_jump_functions_after_inlining on all non-inlined edges that lead out
4167 of this subtree. Newly discovered indirect edges will be added to
4168 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were
4169 created. */
4171 static bool
4172 propagate_info_to_inlined_callees (struct cgraph_edge *cs,
4173 struct cgraph_node *node,
4174 vec<cgraph_edge *> *new_edges)
4176 struct cgraph_edge *e;
4177 bool res;
4179 res = update_indirect_edges_after_inlining (cs, node, new_edges);
4181 for (e = node->callees; e; e = e->next_callee)
4182 if (!e->inline_failed)
4183 res |= propagate_info_to_inlined_callees (cs, e->callee, new_edges);
4184 else
4185 update_jump_functions_after_inlining (cs, e);
4186 for (e = node->indirect_calls; e; e = e->next_callee)
4187 update_jump_functions_after_inlining (cs, e);
4189 return res;
4192 /* Combine two controlled uses counts as done during inlining. */
4194 static int
4195 combine_controlled_uses_counters (int c, int d)
4197 if (c == IPA_UNDESCRIBED_USE || d == IPA_UNDESCRIBED_USE)
4198 return IPA_UNDESCRIBED_USE;
4199 else
4200 return c + d - 1;
4203 /* Propagate number of controlled users from CS->caleee to the new root of the
4204 tree of inlined nodes. */
4206 static void
4207 propagate_controlled_uses (struct cgraph_edge *cs)
4209 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
4210 if (!args)
4211 return;
4212 struct cgraph_node *new_root = cs->caller->inlined_to
4213 ? cs->caller->inlined_to : cs->caller;
4214 ipa_node_params *new_root_info = ipa_node_params_sum->get (new_root);
4215 ipa_node_params *old_root_info = ipa_node_params_sum->get (cs->callee);
4216 int count, i;
4218 if (!old_root_info)
4219 return;
4221 count = MIN (ipa_get_cs_argument_count (args),
4222 ipa_get_param_count (old_root_info));
4223 for (i = 0; i < count; i++)
4225 struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
4226 struct ipa_cst_ref_desc *rdesc;
4228 if (jf->type == IPA_JF_PASS_THROUGH
4229 && !ipa_get_jf_pass_through_refdesc_decremented (jf))
4231 int src_idx, c, d;
4232 src_idx = ipa_get_jf_pass_through_formal_id (jf);
4233 c = ipa_get_controlled_uses (new_root_info, src_idx);
4234 d = ipa_get_controlled_uses (old_root_info, i);
4236 gcc_checking_assert (ipa_get_jf_pass_through_operation (jf)
4237 == NOP_EXPR || c == IPA_UNDESCRIBED_USE);
4238 c = combine_controlled_uses_counters (c, d);
4239 ipa_set_controlled_uses (new_root_info, src_idx, c);
4240 bool lderef = true;
4241 if (c != IPA_UNDESCRIBED_USE)
4243 lderef = (ipa_get_param_load_dereferenced (new_root_info, src_idx)
4244 || ipa_get_param_load_dereferenced (old_root_info, i));
4245 ipa_set_param_load_dereferenced (new_root_info, src_idx, lderef);
4248 if (c == 0 && !lderef && new_root_info->ipcp_orig_node)
4250 struct cgraph_node *n;
4251 struct ipa_ref *ref;
4252 tree t = new_root_info->known_csts[src_idx];
4254 if (t && TREE_CODE (t) == ADDR_EXPR
4255 && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
4256 && (n = cgraph_node::get (TREE_OPERAND (t, 0)))
4257 && (ref = new_root->find_reference (n, NULL, 0,
4258 IPA_REF_ADDR)))
4260 if (dump_file)
4261 fprintf (dump_file, "ipa-prop: Removing cloning-created "
4262 "reference from %s to %s.\n",
4263 new_root->dump_name (),
4264 n->dump_name ());
4265 ref->remove_reference ();
4269 else if (jf->type == IPA_JF_CONST
4270 && (rdesc = jfunc_rdesc_usable (jf)))
4272 int d = ipa_get_controlled_uses (old_root_info, i);
4273 int c = rdesc->refcount;
4274 tree cst = ipa_get_jf_constant (jf);
4275 rdesc->refcount = combine_controlled_uses_counters (c, d);
4276 if (rdesc->refcount != IPA_UNDESCRIBED_USE
4277 && ipa_get_param_load_dereferenced (old_root_info, i)
4278 && TREE_CODE (cst) == ADDR_EXPR
4279 && VAR_P (TREE_OPERAND (cst, 0)))
4281 symtab_node *n = symtab_node::get (TREE_OPERAND (cst, 0));
4282 new_root->create_reference (n, IPA_REF_LOAD, NULL);
4283 if (dump_file)
4284 fprintf (dump_file, "ipa-prop: Address IPA constant will reach "
4285 "a load so adding LOAD reference from %s to %s.\n",
4286 new_root->dump_name (), n->dump_name ());
4288 if (rdesc->refcount == 0)
4290 gcc_checking_assert (TREE_CODE (cst) == ADDR_EXPR
4291 && ((TREE_CODE (TREE_OPERAND (cst, 0))
4292 == FUNCTION_DECL)
4293 || VAR_P (TREE_OPERAND (cst, 0))));
4295 symtab_node *n = symtab_node::get (TREE_OPERAND (cst, 0));
4296 if (n)
4298 remove_described_reference (n, rdesc);
4299 cgraph_node *clone = cs->caller;
4300 while (clone->inlined_to
4301 && clone->ipcp_clone
4302 && clone != rdesc->cs->caller)
4304 struct ipa_ref *ref;
4305 ref = clone->find_reference (n, NULL, 0, IPA_REF_ADDR);
4306 if (ref)
4308 if (dump_file)
4309 fprintf (dump_file, "ipa-prop: Removing "
4310 "cloning-created reference "
4311 "from %s to %s.\n",
4312 clone->dump_name (),
4313 n->dump_name ());
4314 ref->remove_reference ();
4316 clone = clone->callers->caller;
4323 for (i = ipa_get_param_count (old_root_info);
4324 i < ipa_get_cs_argument_count (args);
4325 i++)
4327 struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
4329 if (jf->type == IPA_JF_CONST)
4331 struct ipa_cst_ref_desc *rdesc = jfunc_rdesc_usable (jf);
4332 if (rdesc)
4333 rdesc->refcount = IPA_UNDESCRIBED_USE;
4335 else if (jf->type == IPA_JF_PASS_THROUGH)
4336 ipa_set_controlled_uses (new_root_info,
4337 jf->value.pass_through.formal_id,
4338 IPA_UNDESCRIBED_USE);
4342 /* Update jump functions and call note functions on inlining the call site CS.
4343 CS is expected to lead to a node already cloned by
4344 cgraph_clone_inline_nodes. Newly discovered indirect edges will be added to
4345 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were +
4346 created. */
4348 bool
4349 ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
4350 vec<cgraph_edge *> *new_edges)
4352 bool changed;
4353 /* Do nothing if the preparation phase has not been carried out yet
4354 (i.e. during early inlining). */
4355 if (!ipa_node_params_sum)
4356 return false;
4357 gcc_assert (ipa_edge_args_sum);
4359 propagate_controlled_uses (cs);
4360 changed = propagate_info_to_inlined_callees (cs, cs->callee, new_edges);
4361 ipa_node_params_sum->remove (cs->callee);
4363 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
4364 if (args)
4366 bool ok = true;
4367 if (args->jump_functions)
4369 struct ipa_jump_func *jf;
4370 int i;
4371 FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
4372 if (jf->type == IPA_JF_CONST
4373 && ipa_get_jf_constant_rdesc (jf))
4375 ok = false;
4376 break;
4379 if (ok)
4380 ipa_edge_args_sum->remove (cs);
4382 if (ipcp_transformation_sum)
4383 ipcp_transformation_sum->remove (cs->callee);
4385 return changed;
4388 /* Ensure that array of edge arguments infos is big enough to accommodate a
4389 structure for all edges and reallocates it if not. Also, allocate
4390 associated hash tables is they do not already exist. */
4392 void
4393 ipa_check_create_edge_args (void)
4395 if (!ipa_edge_args_sum)
4396 ipa_edge_args_sum
4397 = (new (ggc_alloc_no_dtor<ipa_edge_args_sum_t> ())
4398 ipa_edge_args_sum_t (symtab, true));
4399 if (!ipa_bits_hash_table)
4400 ipa_bits_hash_table = hash_table<ipa_bit_ggc_hash_traits>::create_ggc (37);
4401 if (!ipa_vr_hash_table)
4402 ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
4405 /* Free all ipa_edge structures. */
4407 void
4408 ipa_free_all_edge_args (void)
4410 if (!ipa_edge_args_sum)
4411 return;
4413 ggc_delete (ipa_edge_args_sum);
4414 ipa_edge_args_sum = NULL;
4417 /* Free all ipa_node_params structures. */
4419 void
4420 ipa_free_all_node_params (void)
4422 if (ipa_node_params_sum)
4423 ggc_delete (ipa_node_params_sum);
4424 ipa_node_params_sum = NULL;
4427 /* Initialize IPA CP transformation summary and also allocate any necessary hash
4428 tables if they do not already exist. */
4430 void
4431 ipcp_transformation_initialize (void)
4433 if (!ipa_bits_hash_table)
4434 ipa_bits_hash_table = hash_table<ipa_bit_ggc_hash_traits>::create_ggc (37);
4435 if (!ipa_vr_hash_table)
4436 ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
4437 if (ipcp_transformation_sum == NULL)
4439 ipcp_transformation_sum = ipcp_transformation_t::create_ggc (symtab);
4440 ipcp_transformation_sum->disable_insertion_hook ();
4444 /* Release the IPA CP transformation summary. */
4446 void
4447 ipcp_free_transformation_sum (void)
4449 if (!ipcp_transformation_sum)
4450 return;
4452 ipcp_transformation_sum->~function_summary<ipcp_transformation *> ();
4453 ggc_free (ipcp_transformation_sum);
4454 ipcp_transformation_sum = NULL;
4457 /* Set the aggregate replacements of NODE to be AGGVALS. */
4459 void
4460 ipa_set_node_agg_value_chain (struct cgraph_node *node,
4461 vec<ipa_argagg_value, va_gc> *aggs)
4463 ipcp_transformation_initialize ();
4464 ipcp_transformation *s = ipcp_transformation_sum->get_create (node);
4465 s->m_agg_values = aggs;
4468 /* Hook that is called by cgraph.cc when an edge is removed. Adjust reference
4469 count data structures accordingly. */
4471 void
4472 ipa_edge_args_sum_t::remove (cgraph_edge *cs, ipa_edge_args *args)
4474 if (args->jump_functions)
4476 struct ipa_jump_func *jf;
4477 int i;
4478 FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
4480 struct ipa_cst_ref_desc *rdesc;
4481 try_decrement_rdesc_refcount (jf);
4482 if (jf->type == IPA_JF_CONST
4483 && (rdesc = ipa_get_jf_constant_rdesc (jf))
4484 && rdesc->cs == cs)
4485 rdesc->cs = NULL;
4490 /* Method invoked when an edge is duplicated. Copy ipa_edge_args and adjust
4491 reference count data strucutres accordingly. */
4493 void
4494 ipa_edge_args_sum_t::duplicate (cgraph_edge *src, cgraph_edge *dst,
4495 ipa_edge_args *old_args, ipa_edge_args *new_args)
4497 unsigned int i;
4499 new_args->jump_functions = vec_safe_copy (old_args->jump_functions);
4500 if (old_args->polymorphic_call_contexts)
4501 new_args->polymorphic_call_contexts
4502 = vec_safe_copy (old_args->polymorphic_call_contexts);
4504 for (i = 0; i < vec_safe_length (old_args->jump_functions); i++)
4506 struct ipa_jump_func *src_jf = ipa_get_ith_jump_func (old_args, i);
4507 struct ipa_jump_func *dst_jf = ipa_get_ith_jump_func (new_args, i);
4509 dst_jf->agg.items = vec_safe_copy (dst_jf->agg.items);
4511 if (src_jf->type == IPA_JF_CONST)
4513 struct ipa_cst_ref_desc *src_rdesc = jfunc_rdesc_usable (src_jf);
4515 if (!src_rdesc)
4516 dst_jf->value.constant.rdesc = NULL;
4517 else if (src->caller == dst->caller)
4519 /* Creation of a speculative edge. If the source edge is the one
4520 grabbing a reference, we must create a new (duplicate)
4521 reference description. Otherwise they refer to the same
4522 description corresponding to a reference taken in a function
4523 src->caller is inlined to. In that case we just must
4524 increment the refcount. */
4525 if (src_rdesc->cs == src)
4527 symtab_node *n = symtab_node_for_jfunc (src_jf);
4528 gcc_checking_assert (n);
4529 ipa_ref *ref
4530 = src->caller->find_reference (n, src->call_stmt,
4531 src->lto_stmt_uid,
4532 IPA_REF_ADDR);
4533 gcc_checking_assert (ref);
4534 dst->caller->clone_reference (ref, ref->stmt);
4536 ipa_cst_ref_desc *dst_rdesc = ipa_refdesc_pool.allocate ();
4537 dst_rdesc->cs = dst;
4538 dst_rdesc->refcount = src_rdesc->refcount;
4539 dst_rdesc->next_duplicate = NULL;
4540 dst_jf->value.constant.rdesc = dst_rdesc;
4542 else
4544 src_rdesc->refcount++;
4545 dst_jf->value.constant.rdesc = src_rdesc;
4548 else if (src_rdesc->cs == src)
4550 struct ipa_cst_ref_desc *dst_rdesc = ipa_refdesc_pool.allocate ();
4551 dst_rdesc->cs = dst;
4552 dst_rdesc->refcount = src_rdesc->refcount;
4553 dst_rdesc->next_duplicate = src_rdesc->next_duplicate;
4554 src_rdesc->next_duplicate = dst_rdesc;
4555 dst_jf->value.constant.rdesc = dst_rdesc;
4557 else
4559 struct ipa_cst_ref_desc *dst_rdesc;
4560 /* This can happen during inlining, when a JFUNC can refer to a
4561 reference taken in a function up in the tree of inline clones.
4562 We need to find the duplicate that refers to our tree of
4563 inline clones. */
4565 gcc_assert (dst->caller->inlined_to);
4566 for (dst_rdesc = src_rdesc->next_duplicate;
4567 dst_rdesc;
4568 dst_rdesc = dst_rdesc->next_duplicate)
4570 struct cgraph_node *top;
4571 top = dst_rdesc->cs->caller->inlined_to
4572 ? dst_rdesc->cs->caller->inlined_to
4573 : dst_rdesc->cs->caller;
4574 if (dst->caller->inlined_to == top)
4575 break;
4577 gcc_assert (dst_rdesc);
4578 dst_jf->value.constant.rdesc = dst_rdesc;
4581 else if (dst_jf->type == IPA_JF_PASS_THROUGH
4582 && src->caller == dst->caller)
4584 struct cgraph_node *inline_root = dst->caller->inlined_to
4585 ? dst->caller->inlined_to : dst->caller;
4586 ipa_node_params *root_info = ipa_node_params_sum->get (inline_root);
4587 int idx = ipa_get_jf_pass_through_formal_id (dst_jf);
4589 int c = ipa_get_controlled_uses (root_info, idx);
4590 if (c != IPA_UNDESCRIBED_USE)
4592 c++;
4593 ipa_set_controlled_uses (root_info, idx, c);
4599 /* Analyze newly added function into callgraph. */
4601 static void
4602 ipa_add_new_function (cgraph_node *node, void *data ATTRIBUTE_UNUSED)
4604 if (node->has_gimple_body_p ())
4605 ipa_analyze_node (node);
4608 /* Hook that is called by summary when a node is duplicated. */
4610 void
4611 ipa_node_params_t::duplicate(cgraph_node *, cgraph_node *,
4612 ipa_node_params *old_info,
4613 ipa_node_params *new_info)
4615 new_info->descriptors = vec_safe_copy (old_info->descriptors);
4616 new_info->lattices = NULL;
4617 new_info->ipcp_orig_node = old_info->ipcp_orig_node;
4618 new_info->known_csts = old_info->known_csts.copy ();
4619 new_info->known_contexts = old_info->known_contexts.copy ();
4621 new_info->analysis_done = old_info->analysis_done;
4622 new_info->node_enqueued = old_info->node_enqueued;
4623 new_info->versionable = old_info->versionable;
4626 /* Duplication of ipcp transformation summaries. */
4628 void
4629 ipcp_transformation_t::duplicate(cgraph_node *, cgraph_node *dst,
4630 ipcp_transformation *src_trans,
4631 ipcp_transformation *dst_trans)
4633 /* Avoid redundant work of duplicating vectors we will never use. */
4634 if (dst->inlined_to)
4635 return;
4636 dst_trans->m_agg_values = vec_safe_copy (src_trans->m_agg_values);
4637 dst_trans->bits = vec_safe_copy (src_trans->bits);
4638 dst_trans->m_vr = vec_safe_copy (src_trans->m_vr);
4641 /* Register our cgraph hooks if they are not already there. */
4643 void
4644 ipa_register_cgraph_hooks (void)
4646 ipa_check_create_node_params ();
4647 ipa_check_create_edge_args ();
4649 function_insertion_hook_holder =
4650 symtab->add_cgraph_insertion_hook (&ipa_add_new_function, NULL);
4653 /* Unregister our cgraph hooks if they are not already there. */
4655 static void
4656 ipa_unregister_cgraph_hooks (void)
4658 if (function_insertion_hook_holder)
4659 symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
4660 function_insertion_hook_holder = NULL;
4663 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
4664 longer needed after ipa-cp. */
4666 void
4667 ipa_free_all_structures_after_ipa_cp (void)
4669 if (!optimize && !in_lto_p)
4671 ipa_free_all_edge_args ();
4672 ipa_free_all_node_params ();
4673 ipcp_sources_pool.release ();
4674 ipcp_cst_values_pool.release ();
4675 ipcp_poly_ctx_values_pool.release ();
4676 ipcp_agg_lattice_pool.release ();
4677 ipa_unregister_cgraph_hooks ();
4678 ipa_refdesc_pool.release ();
4682 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
4683 longer needed after indirect inlining. */
4685 void
4686 ipa_free_all_structures_after_iinln (void)
4688 ipa_free_all_edge_args ();
4689 ipa_free_all_node_params ();
4690 ipa_unregister_cgraph_hooks ();
4691 ipcp_sources_pool.release ();
4692 ipcp_cst_values_pool.release ();
4693 ipcp_poly_ctx_values_pool.release ();
4694 ipcp_agg_lattice_pool.release ();
4695 ipa_refdesc_pool.release ();
4698 /* Print ipa_tree_map data structures of all functions in the
4699 callgraph to F. */
4701 void
4702 ipa_print_node_params (FILE *f, struct cgraph_node *node)
4704 int i, count;
4705 class ipa_node_params *info;
4707 if (!node->definition)
4708 return;
4709 info = ipa_node_params_sum->get (node);
4710 fprintf (f, " function %s parameter descriptors:\n", node->dump_name ());
4711 if (!info)
4713 fprintf (f, " no params return\n");
4714 return;
4716 count = ipa_get_param_count (info);
4717 for (i = 0; i < count; i++)
4719 int c;
4721 fprintf (f, " ");
4722 ipa_dump_param (f, info, i);
4723 if (ipa_is_param_used (info, i))
4724 fprintf (f, " used");
4725 if (ipa_is_param_used_by_ipa_predicates (info, i))
4726 fprintf (f, " used_by_ipa_predicates");
4727 if (ipa_is_param_used_by_indirect_call (info, i))
4728 fprintf (f, " used_by_indirect_call");
4729 if (ipa_is_param_used_by_polymorphic_call (info, i))
4730 fprintf (f, " used_by_polymorphic_call");
4731 c = ipa_get_controlled_uses (info, i);
4732 if (c == IPA_UNDESCRIBED_USE)
4733 fprintf (f, " undescribed_use");
4734 else
4735 fprintf (f, " controlled_uses=%i %s", c,
4736 ipa_get_param_load_dereferenced (info, i)
4737 ? "(load_dereferenced)" : "");
4738 fprintf (f, "\n");
4742 /* Print ipa_tree_map data structures of all functions in the
4743 callgraph to F. */
4745 void
4746 ipa_print_all_params (FILE * f)
4748 struct cgraph_node *node;
4750 fprintf (f, "\nFunction parameters:\n");
4751 FOR_EACH_FUNCTION (node)
4752 ipa_print_node_params (f, node);
4755 /* Stream out jump function JUMP_FUNC to OB. */
4757 static void
4758 ipa_write_jump_function (struct output_block *ob,
4759 struct ipa_jump_func *jump_func)
4761 struct ipa_agg_jf_item *item;
4762 struct bitpack_d bp;
4763 int i, count;
4764 int flag = 0;
4766 /* ADDR_EXPRs are very comon IP invariants; save some streamer data
4767 as well as WPA memory by handling them specially. */
4768 if (jump_func->type == IPA_JF_CONST
4769 && TREE_CODE (jump_func->value.constant.value) == ADDR_EXPR)
4770 flag = 1;
4772 streamer_write_uhwi (ob, jump_func->type * 2 + flag);
4773 switch (jump_func->type)
4775 case IPA_JF_UNKNOWN:
4776 break;
4777 case IPA_JF_CONST:
4778 gcc_assert (
4779 EXPR_LOCATION (jump_func->value.constant.value) == UNKNOWN_LOCATION);
4780 stream_write_tree (ob,
4781 flag
4782 ? TREE_OPERAND (jump_func->value.constant.value, 0)
4783 : jump_func->value.constant.value, true);
4784 break;
4785 case IPA_JF_PASS_THROUGH:
4786 streamer_write_uhwi (ob, jump_func->value.pass_through.operation);
4787 if (jump_func->value.pass_through.operation == NOP_EXPR)
4789 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4790 bp = bitpack_create (ob->main_stream);
4791 bp_pack_value (&bp, jump_func->value.pass_through.agg_preserved, 1);
4792 gcc_assert (!jump_func->value.pass_through.refdesc_decremented);
4793 streamer_write_bitpack (&bp);
4795 else if (TREE_CODE_CLASS (jump_func->value.pass_through.operation)
4796 == tcc_unary)
4797 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4798 else
4800 stream_write_tree (ob, jump_func->value.pass_through.operand, true);
4801 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4803 break;
4804 case IPA_JF_ANCESTOR:
4805 streamer_write_uhwi (ob, jump_func->value.ancestor.offset);
4806 streamer_write_uhwi (ob, jump_func->value.ancestor.formal_id);
4807 bp = bitpack_create (ob->main_stream);
4808 bp_pack_value (&bp, jump_func->value.ancestor.agg_preserved, 1);
4809 bp_pack_value (&bp, jump_func->value.ancestor.keep_null, 1);
4810 streamer_write_bitpack (&bp);
4811 break;
4812 default:
4813 fatal_error (UNKNOWN_LOCATION, "invalid jump function in LTO stream");
4816 count = vec_safe_length (jump_func->agg.items);
4817 streamer_write_uhwi (ob, count);
4818 if (count)
4820 bp = bitpack_create (ob->main_stream);
4821 bp_pack_value (&bp, jump_func->agg.by_ref, 1);
4822 streamer_write_bitpack (&bp);
4825 FOR_EACH_VEC_SAFE_ELT (jump_func->agg.items, i, item)
4827 stream_write_tree (ob, item->type, true);
4828 streamer_write_uhwi (ob, item->offset);
4829 streamer_write_uhwi (ob, item->jftype);
4830 switch (item->jftype)
4832 case IPA_JF_UNKNOWN:
4833 break;
4834 case IPA_JF_CONST:
4835 stream_write_tree (ob, item->value.constant, true);
4836 break;
4837 case IPA_JF_PASS_THROUGH:
4838 case IPA_JF_LOAD_AGG:
4839 streamer_write_uhwi (ob, item->value.pass_through.operation);
4840 streamer_write_uhwi (ob, item->value.pass_through.formal_id);
4841 if (TREE_CODE_CLASS (item->value.pass_through.operation)
4842 != tcc_unary)
4843 stream_write_tree (ob, item->value.pass_through.operand, true);
4844 if (item->jftype == IPA_JF_LOAD_AGG)
4846 stream_write_tree (ob, item->value.load_agg.type, true);
4847 streamer_write_uhwi (ob, item->value.load_agg.offset);
4848 bp = bitpack_create (ob->main_stream);
4849 bp_pack_value (&bp, item->value.load_agg.by_ref, 1);
4850 streamer_write_bitpack (&bp);
4852 break;
4853 default:
4854 fatal_error (UNKNOWN_LOCATION,
4855 "invalid jump function in LTO stream");
4859 bp = bitpack_create (ob->main_stream);
4860 bp_pack_value (&bp, !!jump_func->bits, 1);
4861 streamer_write_bitpack (&bp);
4862 if (jump_func->bits)
4864 streamer_write_widest_int (ob, jump_func->bits->value);
4865 streamer_write_widest_int (ob, jump_func->bits->mask);
4867 bp_pack_value (&bp, !!jump_func->m_vr, 1);
4868 streamer_write_bitpack (&bp);
4869 if (jump_func->m_vr)
4871 tree min, max;
4872 value_range_kind kind = get_legacy_range (*jump_func->m_vr, min, max);
4873 streamer_write_enum (ob->main_stream, value_rang_type,
4874 VR_LAST, kind);
4875 stream_write_tree (ob, min, true);
4876 stream_write_tree (ob, max, true);
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 struct bitpack_d vr_bp = streamer_read_bitpack (ib);
5010 bool vr_known = bp_unpack_value (&vr_bp, 1);
5011 if (vr_known)
5013 enum value_range_kind type = streamer_read_enum (ib, value_range_kind,
5014 VR_LAST);
5015 tree min = stream_read_tree (ib, data_in);
5016 tree max = stream_read_tree (ib, data_in);
5017 if (prevails)
5018 ipa_set_jfunc_vr (jump_func, type, min, max);
5020 else
5021 jump_func->m_vr = NULL;
5024 /* Stream out parts of cgraph_indirect_call_info corresponding to CS that are
5025 relevant to indirect inlining to OB. */
5027 static void
5028 ipa_write_indirect_edge_info (struct output_block *ob,
5029 struct cgraph_edge *cs)
5031 class cgraph_indirect_call_info *ii = cs->indirect_info;
5032 struct bitpack_d bp;
5034 streamer_write_hwi (ob, ii->param_index);
5035 bp = bitpack_create (ob->main_stream);
5036 bp_pack_value (&bp, ii->polymorphic, 1);
5037 bp_pack_value (&bp, ii->agg_contents, 1);
5038 bp_pack_value (&bp, ii->member_ptr, 1);
5039 bp_pack_value (&bp, ii->by_ref, 1);
5040 bp_pack_value (&bp, ii->guaranteed_unmodified, 1);
5041 bp_pack_value (&bp, ii->vptr_changed, 1);
5042 streamer_write_bitpack (&bp);
5043 if (ii->agg_contents || ii->polymorphic)
5044 streamer_write_hwi (ob, ii->offset);
5045 else
5046 gcc_assert (ii->offset == 0);
5048 if (ii->polymorphic)
5050 streamer_write_hwi (ob, ii->otr_token);
5051 stream_write_tree (ob, ii->otr_type, true);
5052 ii->context.stream_out (ob);
5056 /* Read in parts of cgraph_indirect_call_info corresponding to CS that are
5057 relevant to indirect inlining from IB. */
5059 static void
5060 ipa_read_indirect_edge_info (class lto_input_block *ib,
5061 class data_in *data_in,
5062 struct cgraph_edge *cs,
5063 class ipa_node_params *info)
5065 class cgraph_indirect_call_info *ii = cs->indirect_info;
5066 struct bitpack_d bp;
5068 ii->param_index = (int) streamer_read_hwi (ib);
5069 bp = streamer_read_bitpack (ib);
5070 ii->polymorphic = bp_unpack_value (&bp, 1);
5071 ii->agg_contents = bp_unpack_value (&bp, 1);
5072 ii->member_ptr = bp_unpack_value (&bp, 1);
5073 ii->by_ref = bp_unpack_value (&bp, 1);
5074 ii->guaranteed_unmodified = bp_unpack_value (&bp, 1);
5075 ii->vptr_changed = bp_unpack_value (&bp, 1);
5076 if (ii->agg_contents || ii->polymorphic)
5077 ii->offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
5078 else
5079 ii->offset = 0;
5080 if (ii->polymorphic)
5082 ii->otr_token = (HOST_WIDE_INT) streamer_read_hwi (ib);
5083 ii->otr_type = stream_read_tree (ib, data_in);
5084 ii->context.stream_in (ib, data_in);
5086 if (info && ii->param_index >= 0)
5088 if (ii->polymorphic)
5089 ipa_set_param_used_by_polymorphic_call (info,
5090 ii->param_index , true);
5091 ipa_set_param_used_by_indirect_call (info,
5092 ii->param_index, true);
5096 /* Stream out NODE info to OB. */
5098 static void
5099 ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
5101 int node_ref;
5102 lto_symtab_encoder_t encoder;
5103 ipa_node_params *info = ipa_node_params_sum->get (node);
5104 int j;
5105 struct cgraph_edge *e;
5106 struct bitpack_d bp;
5108 encoder = ob->decl_state->symtab_node_encoder;
5109 node_ref = lto_symtab_encoder_encode (encoder, node);
5110 streamer_write_uhwi (ob, node_ref);
5112 streamer_write_uhwi (ob, ipa_get_param_count (info));
5113 for (j = 0; j < ipa_get_param_count (info); j++)
5114 streamer_write_uhwi (ob, ipa_get_param_move_cost (info, j));
5115 bp = bitpack_create (ob->main_stream);
5116 gcc_assert (info->analysis_done
5117 || ipa_get_param_count (info) == 0);
5118 gcc_assert (!info->node_enqueued);
5119 gcc_assert (!info->ipcp_orig_node);
5120 for (j = 0; j < ipa_get_param_count (info); j++)
5122 /* TODO: We could just not stream the bit in the undescribed case. */
5123 bool d = (ipa_get_controlled_uses (info, j) != IPA_UNDESCRIBED_USE)
5124 ? ipa_get_param_load_dereferenced (info, j) : true;
5125 bp_pack_value (&bp, d, 1);
5126 bp_pack_value (&bp, ipa_is_param_used (info, j), 1);
5128 streamer_write_bitpack (&bp);
5129 for (j = 0; j < ipa_get_param_count (info); j++)
5131 streamer_write_hwi (ob, ipa_get_controlled_uses (info, j));
5132 stream_write_tree (ob, ipa_get_type (info, j), true);
5134 for (e = node->callees; e; e = e->next_callee)
5136 ipa_edge_args *args = ipa_edge_args_sum->get (e);
5138 if (!args)
5140 streamer_write_uhwi (ob, 0);
5141 continue;
5144 streamer_write_uhwi (ob,
5145 ipa_get_cs_argument_count (args) * 2
5146 + (args->polymorphic_call_contexts != NULL));
5147 for (j = 0; j < ipa_get_cs_argument_count (args); j++)
5149 ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
5150 if (args->polymorphic_call_contexts != NULL)
5151 ipa_get_ith_polymorhic_call_context (args, j)->stream_out (ob);
5154 for (e = node->indirect_calls; e; e = e->next_callee)
5156 ipa_edge_args *args = ipa_edge_args_sum->get (e);
5157 if (!args)
5158 streamer_write_uhwi (ob, 0);
5159 else
5161 streamer_write_uhwi (ob,
5162 ipa_get_cs_argument_count (args) * 2
5163 + (args->polymorphic_call_contexts != NULL));
5164 for (j = 0; j < ipa_get_cs_argument_count (args); j++)
5166 ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
5167 if (args->polymorphic_call_contexts != NULL)
5168 ipa_get_ith_polymorhic_call_context (args, j)->stream_out (ob);
5171 ipa_write_indirect_edge_info (ob, e);
5175 /* Stream in edge E from IB. */
5177 static void
5178 ipa_read_edge_info (class lto_input_block *ib,
5179 class data_in *data_in,
5180 struct cgraph_edge *e, bool prevails)
5182 int count = streamer_read_uhwi (ib);
5183 bool contexts_computed = count & 1;
5185 count /= 2;
5186 if (!count)
5187 return;
5188 if (prevails
5189 && (e->possibly_call_in_translation_unit_p ()
5190 /* Also stream in jump functions to builtins in hope that they
5191 will get fnspecs. */
5192 || fndecl_built_in_p (e->callee->decl, BUILT_IN_NORMAL)))
5194 ipa_edge_args *args = ipa_edge_args_sum->get_create (e);
5195 vec_safe_grow_cleared (args->jump_functions, count, true);
5196 if (contexts_computed)
5197 vec_safe_grow_cleared (args->polymorphic_call_contexts, count, true);
5198 for (int k = 0; k < count; k++)
5200 ipa_read_jump_function (ib, ipa_get_ith_jump_func (args, k), e,
5201 data_in, prevails);
5202 if (contexts_computed)
5203 ipa_get_ith_polymorhic_call_context (args, k)->stream_in
5204 (ib, data_in);
5207 else
5209 for (int k = 0; k < count; k++)
5211 struct ipa_jump_func dummy;
5212 ipa_read_jump_function (ib, &dummy, e,
5213 data_in, prevails);
5214 if (contexts_computed)
5216 class ipa_polymorphic_call_context ctx;
5217 ctx.stream_in (ib, data_in);
5223 /* Stream in NODE info from IB. */
5225 static void
5226 ipa_read_node_info (class lto_input_block *ib, struct cgraph_node *node,
5227 class data_in *data_in)
5229 int k;
5230 struct cgraph_edge *e;
5231 struct bitpack_d bp;
5232 bool prevails = node->prevailing_p ();
5233 ipa_node_params *info
5234 = prevails ? ipa_node_params_sum->get_create (node) : NULL;
5236 int param_count = streamer_read_uhwi (ib);
5237 if (prevails)
5239 ipa_alloc_node_params (node, param_count);
5240 for (k = 0; k < param_count; k++)
5241 (*info->descriptors)[k].move_cost = streamer_read_uhwi (ib);
5242 if (ipa_get_param_count (info) != 0)
5243 info->analysis_done = true;
5244 info->node_enqueued = false;
5246 else
5247 for (k = 0; k < param_count; k++)
5248 streamer_read_uhwi (ib);
5250 bp = streamer_read_bitpack (ib);
5251 for (k = 0; k < param_count; k++)
5253 bool load_dereferenced = bp_unpack_value (&bp, 1);
5254 bool used = bp_unpack_value (&bp, 1);
5256 if (prevails)
5258 ipa_set_param_load_dereferenced (info, k, load_dereferenced);
5259 ipa_set_param_used (info, k, used);
5262 for (k = 0; k < param_count; k++)
5264 int nuses = streamer_read_hwi (ib);
5265 tree type = stream_read_tree (ib, data_in);
5267 if (prevails)
5269 ipa_set_controlled_uses (info, k, nuses);
5270 (*info->descriptors)[k].decl_or_type = type;
5273 for (e = node->callees; e; e = e->next_callee)
5274 ipa_read_edge_info (ib, data_in, e, prevails);
5275 for (e = node->indirect_calls; e; e = e->next_callee)
5277 ipa_read_edge_info (ib, data_in, e, prevails);
5278 ipa_read_indirect_edge_info (ib, data_in, e, info);
5282 /* Write jump functions for nodes in SET. */
5284 void
5285 ipa_prop_write_jump_functions (void)
5287 struct output_block *ob;
5288 unsigned int count = 0;
5289 lto_symtab_encoder_iterator lsei;
5290 lto_symtab_encoder_t encoder;
5292 if (!ipa_node_params_sum || !ipa_edge_args_sum)
5293 return;
5295 ob = create_output_block (LTO_section_jump_functions);
5296 encoder = ob->decl_state->symtab_node_encoder;
5297 ob->symbol = NULL;
5298 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
5299 lsei_next_function_in_partition (&lsei))
5301 cgraph_node *node = lsei_cgraph_node (lsei);
5302 if (node->has_gimple_body_p ()
5303 && ipa_node_params_sum->get (node) != NULL)
5304 count++;
5307 streamer_write_uhwi (ob, count);
5309 /* Process all of the functions. */
5310 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
5311 lsei_next_function_in_partition (&lsei))
5313 cgraph_node *node = lsei_cgraph_node (lsei);
5314 if (node->has_gimple_body_p ()
5315 && ipa_node_params_sum->get (node) != NULL)
5316 ipa_write_node_info (ob, node);
5318 streamer_write_char_stream (ob->main_stream, 0);
5319 produce_asm (ob, NULL);
5320 destroy_output_block (ob);
5323 /* Read section in file FILE_DATA of length LEN with data DATA. */
5325 static void
5326 ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
5327 size_t len)
5329 const struct lto_function_header *header =
5330 (const struct lto_function_header *) data;
5331 const int cfg_offset = sizeof (struct lto_function_header);
5332 const int main_offset = cfg_offset + header->cfg_size;
5333 const int string_offset = main_offset + header->main_size;
5334 class data_in *data_in;
5335 unsigned int i;
5336 unsigned int count;
5338 lto_input_block ib_main ((const char *) data + main_offset,
5339 header->main_size, file_data->mode_table);
5341 data_in =
5342 lto_data_in_create (file_data, (const char *) data + string_offset,
5343 header->string_size, vNULL);
5344 count = streamer_read_uhwi (&ib_main);
5346 for (i = 0; i < count; i++)
5348 unsigned int index;
5349 struct cgraph_node *node;
5350 lto_symtab_encoder_t encoder;
5352 index = streamer_read_uhwi (&ib_main);
5353 encoder = file_data->symtab_node_encoder;
5354 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
5355 index));
5356 gcc_assert (node->definition);
5357 ipa_read_node_info (&ib_main, node, data_in);
5359 lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
5360 len);
5361 lto_data_in_delete (data_in);
5364 /* Read ipcp jump functions. */
5366 void
5367 ipa_prop_read_jump_functions (void)
5369 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
5370 struct lto_file_decl_data *file_data;
5371 unsigned int j = 0;
5373 ipa_check_create_node_params ();
5374 ipa_check_create_edge_args ();
5375 ipa_register_cgraph_hooks ();
5377 while ((file_data = file_data_vec[j++]))
5379 size_t len;
5380 const char *data
5381 = lto_get_summary_section_data (file_data, LTO_section_jump_functions,
5382 &len);
5383 if (data)
5384 ipa_prop_read_section (file_data, data, len);
5388 /* Return true if the IPA-CP transformation summary TS is non-NULL and contains
5389 useful info. */
5390 static bool
5391 useful_ipcp_transformation_info_p (ipcp_transformation *ts)
5393 if (!ts)
5394 return false;
5395 if (!vec_safe_is_empty (ts->m_agg_values)
5396 || !vec_safe_is_empty (ts->bits)
5397 || !vec_safe_is_empty (ts->m_vr))
5398 return true;
5399 return false;
5402 /* Write into OB IPA-CP transfromation summary TS describing NODE. */
5404 void
5405 write_ipcp_transformation_info (output_block *ob, cgraph_node *node,
5406 ipcp_transformation *ts)
5408 lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
5409 int node_ref = lto_symtab_encoder_encode (encoder, node);
5410 streamer_write_uhwi (ob, node_ref);
5412 streamer_write_uhwi (ob, vec_safe_length (ts->m_agg_values));
5413 for (const ipa_argagg_value &av : ts->m_agg_values)
5415 struct bitpack_d bp;
5417 stream_write_tree (ob, av.value, true);
5418 streamer_write_uhwi (ob, av.unit_offset);
5419 streamer_write_uhwi (ob, av.index);
5421 bp = bitpack_create (ob->main_stream);
5422 bp_pack_value (&bp, av.by_ref, 1);
5423 streamer_write_bitpack (&bp);
5426 streamer_write_uhwi (ob, vec_safe_length (ts->m_vr));
5427 for (const ipa_vr &parm_vr : ts->m_vr)
5428 parm_vr.streamer_write (ob);
5430 streamer_write_uhwi (ob, vec_safe_length (ts->bits));
5431 for (const ipa_bits *bits_jfunc : ts->bits)
5433 struct bitpack_d bp = bitpack_create (ob->main_stream);
5434 bp_pack_value (&bp, !!bits_jfunc, 1);
5435 streamer_write_bitpack (&bp);
5436 if (bits_jfunc)
5438 streamer_write_widest_int (ob, bits_jfunc->value);
5439 streamer_write_widest_int (ob, bits_jfunc->mask);
5444 /* Stream in the aggregate value replacement chain for NODE from IB. */
5446 static void
5447 read_ipcp_transformation_info (lto_input_block *ib, cgraph_node *node,
5448 data_in *data_in)
5450 unsigned int count, i;
5451 ipcp_transformation_initialize ();
5452 ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
5454 count = streamer_read_uhwi (ib);
5455 if (count > 0)
5457 vec_safe_grow_cleared (ts->m_agg_values, count, true);
5458 for (i = 0; i <count; i++)
5460 ipa_argagg_value *av = &(*ts->m_agg_values)[i];;
5462 av->value = stream_read_tree (ib, data_in);
5463 av->unit_offset = streamer_read_uhwi (ib);
5464 av->index = streamer_read_uhwi (ib);
5466 bitpack_d bp = streamer_read_bitpack (ib);
5467 av->by_ref = bp_unpack_value (&bp, 1);
5471 count = streamer_read_uhwi (ib);
5472 if (count > 0)
5474 vec_safe_grow_cleared (ts->m_vr, count, true);
5475 for (i = 0; i < count; i++)
5477 ipa_vr *parm_vr;
5478 parm_vr = &(*ts->m_vr)[i];
5479 parm_vr->streamer_read (ib, data_in);
5482 count = streamer_read_uhwi (ib);
5483 if (count > 0)
5485 vec_safe_grow_cleared (ts->bits, count, true);
5486 for (i = 0; i < count; i++)
5488 struct bitpack_d bp = streamer_read_bitpack (ib);
5489 bool known = bp_unpack_value (&bp, 1);
5490 if (known)
5492 const widest_int value = streamer_read_widest_int (ib);
5493 const widest_int mask = streamer_read_widest_int (ib);
5494 ipa_bits *bits
5495 = ipa_get_ipa_bits_for_value (value, mask);
5496 (*ts->bits)[i] = bits;
5502 /* Write all aggregate replacement for nodes in set. */
5504 void
5505 ipcp_write_transformation_summaries (void)
5507 struct output_block *ob;
5508 unsigned int count = 0;
5509 lto_symtab_encoder_t encoder;
5511 ob = create_output_block (LTO_section_ipcp_transform);
5512 encoder = ob->decl_state->symtab_node_encoder;
5513 ob->symbol = NULL;
5515 for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
5517 symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
5518 cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
5519 if (!cnode)
5520 continue;
5521 ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
5522 if (useful_ipcp_transformation_info_p (ts)
5523 && lto_symtab_encoder_encode_body_p (encoder, cnode))
5524 count++;
5527 streamer_write_uhwi (ob, count);
5529 for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
5531 symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
5532 cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
5533 if (!cnode)
5534 continue;
5535 ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
5536 if (useful_ipcp_transformation_info_p (ts)
5537 && lto_symtab_encoder_encode_body_p (encoder, cnode))
5538 write_ipcp_transformation_info (ob, cnode, ts);
5540 streamer_write_char_stream (ob->main_stream, 0);
5541 produce_asm (ob, NULL);
5542 destroy_output_block (ob);
5545 /* Read replacements section in file FILE_DATA of length LEN with data
5546 DATA. */
5548 static void
5549 read_replacements_section (struct lto_file_decl_data *file_data,
5550 const char *data,
5551 size_t len)
5553 const struct lto_function_header *header =
5554 (const struct lto_function_header *) data;
5555 const int cfg_offset = sizeof (struct lto_function_header);
5556 const int main_offset = cfg_offset + header->cfg_size;
5557 const int string_offset = main_offset + header->main_size;
5558 class data_in *data_in;
5559 unsigned int i;
5560 unsigned int count;
5562 lto_input_block ib_main ((const char *) data + main_offset,
5563 header->main_size, file_data->mode_table);
5565 data_in = lto_data_in_create (file_data, (const char *) data + string_offset,
5566 header->string_size, vNULL);
5567 count = streamer_read_uhwi (&ib_main);
5569 for (i = 0; i < count; i++)
5571 unsigned int index;
5572 struct cgraph_node *node;
5573 lto_symtab_encoder_t encoder;
5575 index = streamer_read_uhwi (&ib_main);
5576 encoder = file_data->symtab_node_encoder;
5577 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
5578 index));
5579 read_ipcp_transformation_info (&ib_main, node, data_in);
5581 lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
5582 len);
5583 lto_data_in_delete (data_in);
5586 /* Read IPA-CP aggregate replacements. */
5588 void
5589 ipcp_read_transformation_summaries (void)
5591 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
5592 struct lto_file_decl_data *file_data;
5593 unsigned int j = 0;
5595 while ((file_data = file_data_vec[j++]))
5597 size_t len;
5598 const char *data
5599 = lto_get_summary_section_data (file_data, LTO_section_ipcp_transform,
5600 &len);
5601 if (data)
5602 read_replacements_section (file_data, data, len);
5606 /* Adjust the aggregate replacements in TS to reflect any parameter removals
5607 which might have already taken place. If after adjustments there are no
5608 aggregate replacements left, the m_agg_values will be set to NULL. In other
5609 cases, it may be shrunk. */
5611 static void
5612 adjust_agg_replacement_values (cgraph_node *node, ipcp_transformation *ts)
5614 clone_info *cinfo = clone_info::get (node);
5615 if (!cinfo || !cinfo->param_adjustments)
5616 return;
5618 auto_vec<int, 16> new_indices;
5619 cinfo->param_adjustments->get_updated_indices (&new_indices);
5620 bool removed_item = false;
5621 unsigned dst_index = 0;
5622 unsigned count = ts->m_agg_values->length ();
5623 for (unsigned i = 0; i < count; i++)
5625 ipa_argagg_value *v = &(*ts->m_agg_values)[i];
5626 gcc_checking_assert (v->index >= 0);
5628 int new_idx = -1;
5629 if ((unsigned) v->index < new_indices.length ())
5630 new_idx = new_indices[v->index];
5632 if (new_idx >= 0)
5634 v->index = new_idx;
5635 if (removed_item)
5636 (*ts->m_agg_values)[dst_index] = *v;
5637 dst_index++;
5639 else
5640 removed_item = true;
5643 if (dst_index == 0)
5645 ggc_free (ts->m_agg_values);
5646 ts->m_agg_values = NULL;
5648 else if (removed_item)
5649 ts->m_agg_values->truncate (dst_index);
5651 return;
5654 /* Dominator walker driving the ipcp modification phase. */
5656 class ipcp_modif_dom_walker : public dom_walker
5658 public:
5659 ipcp_modif_dom_walker (struct ipa_func_body_info *fbi,
5660 vec<ipa_param_descriptor, va_gc> *descs,
5661 ipcp_transformation *ts, bool *sc)
5662 : dom_walker (CDI_DOMINATORS), m_fbi (fbi), m_descriptors (descs),
5663 m_ts (ts), m_something_changed (sc) {}
5665 edge before_dom_children (basic_block) final override;
5666 bool cleanup_eh ()
5667 { return gimple_purge_all_dead_eh_edges (m_need_eh_cleanup); }
5669 private:
5670 struct ipa_func_body_info *m_fbi;
5671 vec<ipa_param_descriptor, va_gc> *m_descriptors;
5672 ipcp_transformation *m_ts;
5673 bool *m_something_changed;
5674 auto_bitmap m_need_eh_cleanup;
5677 edge
5678 ipcp_modif_dom_walker::before_dom_children (basic_block bb)
5680 gimple_stmt_iterator gsi;
5681 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
5683 gimple *stmt = gsi_stmt (gsi);
5684 tree rhs, val, t;
5685 HOST_WIDE_INT bit_offset;
5686 poly_int64 size;
5687 int index;
5688 bool by_ref, vce;
5690 if (!gimple_assign_load_p (stmt))
5691 continue;
5692 rhs = gimple_assign_rhs1 (stmt);
5693 if (!is_gimple_reg_type (TREE_TYPE (rhs)))
5694 continue;
5696 vce = false;
5697 t = rhs;
5698 while (handled_component_p (t))
5700 /* V_C_E can do things like convert an array of integers to one
5701 bigger integer and similar things we do not handle below. */
5702 if (TREE_CODE (t) == VIEW_CONVERT_EXPR)
5704 vce = true;
5705 break;
5707 t = TREE_OPERAND (t, 0);
5709 if (vce)
5710 continue;
5712 if (!ipa_load_from_parm_agg (m_fbi, m_descriptors, stmt, rhs, &index,
5713 &bit_offset, &size, &by_ref))
5714 continue;
5715 unsigned unit_offset = bit_offset / BITS_PER_UNIT;
5716 ipa_argagg_value_list avl (m_ts);
5717 tree v = avl.get_value (index, unit_offset, by_ref);
5719 if (!v
5720 || maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (v))), size))
5721 continue;
5723 gcc_checking_assert (is_gimple_ip_invariant (v));
5724 if (!useless_type_conversion_p (TREE_TYPE (rhs), TREE_TYPE (v)))
5726 if (fold_convertible_p (TREE_TYPE (rhs), v))
5727 val = fold_build1 (NOP_EXPR, TREE_TYPE (rhs), v);
5728 else if (TYPE_SIZE (TREE_TYPE (rhs))
5729 == TYPE_SIZE (TREE_TYPE (v)))
5730 val = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (rhs), v);
5731 else
5733 if (dump_file)
5735 fprintf (dump_file, " const ");
5736 print_generic_expr (dump_file, v);
5737 fprintf (dump_file, " can't be converted to type of ");
5738 print_generic_expr (dump_file, rhs);
5739 fprintf (dump_file, "\n");
5741 continue;
5744 else
5745 val = v;
5747 if (dump_file && (dump_flags & TDF_DETAILS))
5749 fprintf (dump_file, "Modifying stmt:\n ");
5750 print_gimple_stmt (dump_file, stmt, 0);
5752 gimple_assign_set_rhs_from_tree (&gsi, val);
5753 update_stmt (stmt);
5755 if (dump_file && (dump_flags & TDF_DETAILS))
5757 fprintf (dump_file, "into:\n ");
5758 print_gimple_stmt (dump_file, stmt, 0);
5759 fprintf (dump_file, "\n");
5762 *m_something_changed = true;
5763 if (maybe_clean_eh_stmt (stmt))
5764 bitmap_set_bit (m_need_eh_cleanup, bb->index);
5766 return NULL;
5769 /* Return true if we have recorded VALUE and MASK about PARM.
5770 Set VALUE and MASk accordingly. */
5772 bool
5773 ipcp_get_parm_bits (tree parm, tree *value, widest_int *mask)
5775 cgraph_node *cnode = cgraph_node::get (current_function_decl);
5776 ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
5777 if (!ts || vec_safe_length (ts->bits) == 0)
5778 return false;
5780 int i = 0;
5781 for (tree p = DECL_ARGUMENTS (current_function_decl);
5782 p != parm; p = DECL_CHAIN (p))
5784 i++;
5785 /* Ignore static chain. */
5786 if (!p)
5787 return false;
5790 clone_info *cinfo = clone_info::get (cnode);
5791 if (cinfo && cinfo->param_adjustments)
5793 i = cinfo->param_adjustments->get_original_index (i);
5794 if (i < 0)
5795 return false;
5798 vec<ipa_bits *, va_gc> &bits = *ts->bits;
5799 if (!bits[i])
5800 return false;
5801 *mask = bits[i]->mask;
5802 *value = wide_int_to_tree (TREE_TYPE (parm), bits[i]->value);
5803 return true;
5807 /* Update bits info of formal parameters as described in
5808 ipcp_transformation. */
5810 static void
5811 ipcp_update_bits (struct cgraph_node *node)
5813 ipcp_transformation *ts = ipcp_get_transformation_summary (node);
5815 if (!ts || vec_safe_length (ts->bits) == 0)
5816 return;
5817 vec<ipa_bits *, va_gc> &bits = *ts->bits;
5818 unsigned count = bits.length ();
5819 if (!count)
5820 return;
5822 auto_vec<int, 16> new_indices;
5823 bool need_remapping = false;
5824 clone_info *cinfo = clone_info::get (node);
5825 if (cinfo && cinfo->param_adjustments)
5827 cinfo->param_adjustments->get_updated_indices (&new_indices);
5828 need_remapping = true;
5830 auto_vec <tree, 16> parm_decls;
5831 push_function_arg_decls (&parm_decls, node->decl);
5833 for (unsigned i = 0; i < count; ++i)
5835 tree parm;
5836 if (need_remapping)
5838 if (i >= new_indices.length ())
5839 continue;
5840 int idx = new_indices[i];
5841 if (idx < 0)
5842 continue;
5843 parm = parm_decls[idx];
5845 else
5846 parm = parm_decls[i];
5847 gcc_checking_assert (parm);
5850 if (!bits[i]
5851 || !(INTEGRAL_TYPE_P (TREE_TYPE (parm))
5852 || POINTER_TYPE_P (TREE_TYPE (parm)))
5853 || !is_gimple_reg (parm))
5854 continue;
5856 tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl), parm);
5857 if (!ddef)
5858 continue;
5860 if (dump_file)
5862 fprintf (dump_file, "Adjusting mask for param %u to ", i);
5863 print_hex (bits[i]->mask, dump_file);
5864 fprintf (dump_file, "\n");
5867 if (INTEGRAL_TYPE_P (TREE_TYPE (ddef)))
5869 unsigned prec = TYPE_PRECISION (TREE_TYPE (ddef));
5870 signop sgn = TYPE_SIGN (TREE_TYPE (ddef));
5872 wide_int nonzero_bits = wide_int::from (bits[i]->mask, prec, UNSIGNED)
5873 | wide_int::from (bits[i]->value, prec, sgn);
5874 set_nonzero_bits (ddef, nonzero_bits);
5876 else
5878 unsigned tem = bits[i]->mask.to_uhwi ();
5879 unsigned HOST_WIDE_INT bitpos = bits[i]->value.to_uhwi ();
5880 unsigned align = tem & -tem;
5881 unsigned misalign = bitpos & (align - 1);
5883 if (align > 1)
5885 if (dump_file)
5886 fprintf (dump_file, "Adjusting align: %u, misalign: %u\n", align, misalign);
5888 unsigned old_align, old_misalign;
5889 struct ptr_info_def *pi = get_ptr_info (ddef);
5890 bool old_known = get_ptr_info_alignment (pi, &old_align, &old_misalign);
5892 if (old_known
5893 && old_align > align)
5895 if (dump_file)
5897 fprintf (dump_file, "But alignment was already %u.\n", old_align);
5898 if ((old_misalign & (align - 1)) != misalign)
5899 fprintf (dump_file, "old_misalign (%u) and misalign (%u) mismatch\n",
5900 old_misalign, misalign);
5902 continue;
5905 if (old_known
5906 && ((misalign & (old_align - 1)) != old_misalign)
5907 && dump_file)
5908 fprintf (dump_file, "old_misalign (%u) and misalign (%u) mismatch\n",
5909 old_misalign, misalign);
5911 set_ptr_info_alignment (pi, align, misalign);
5917 /* Update value range of formal parameters as described in
5918 ipcp_transformation. */
5920 static void
5921 ipcp_update_vr (struct cgraph_node *node)
5923 ipcp_transformation *ts = ipcp_get_transformation_summary (node);
5924 if (!ts || vec_safe_length (ts->m_vr) == 0)
5925 return;
5926 const vec<ipa_vr, va_gc> &vr = *ts->m_vr;
5927 unsigned count = vr.length ();
5928 if (!count)
5929 return;
5931 auto_vec<int, 16> new_indices;
5932 bool need_remapping = false;
5933 clone_info *cinfo = clone_info::get (node);
5934 if (cinfo && cinfo->param_adjustments)
5936 cinfo->param_adjustments->get_updated_indices (&new_indices);
5937 need_remapping = true;
5939 auto_vec <tree, 16> parm_decls;
5940 push_function_arg_decls (&parm_decls, node->decl);
5942 for (unsigned i = 0; i < count; ++i)
5944 tree parm;
5945 int remapped_idx;
5946 if (need_remapping)
5948 if (i >= new_indices.length ())
5949 continue;
5950 remapped_idx = new_indices[i];
5951 if (remapped_idx < 0)
5952 continue;
5954 else
5955 remapped_idx = i;
5957 parm = parm_decls[remapped_idx];
5959 gcc_checking_assert (parm);
5960 tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl), parm);
5962 if (!ddef || !is_gimple_reg (parm))
5963 continue;
5965 if (vr[i].known_p ())
5967 value_range tmp;
5968 vr[i].get_vrange (tmp);
5970 if (!tmp.undefined_p () && !tmp.varying_p ())
5972 if (dump_file)
5974 fprintf (dump_file, "Setting value range of param %u "
5975 "(now %i) ", i, remapped_idx);
5976 tmp.dump (dump_file);
5977 fprintf (dump_file, "]\n");
5979 set_range_info (ddef, tmp);
5985 /* IPCP transformation phase doing propagation of aggregate values. */
5987 unsigned int
5988 ipcp_transform_function (struct cgraph_node *node)
5990 struct ipa_func_body_info fbi;
5991 int param_count;
5993 gcc_checking_assert (cfun);
5994 gcc_checking_assert (current_function_decl);
5996 if (dump_file)
5997 fprintf (dump_file, "Modification phase of node %s\n",
5998 node->dump_name ());
6000 ipcp_update_bits (node);
6001 ipcp_update_vr (node);
6002 ipcp_transformation *ts = ipcp_get_transformation_summary (node);
6003 if (!ts || vec_safe_is_empty (ts->m_agg_values))
6004 return 0;
6005 param_count = count_formal_params (node->decl);
6006 if (param_count == 0)
6007 return 0;
6009 adjust_agg_replacement_values (node, ts);
6010 if (vec_safe_is_empty (ts->m_agg_values))
6012 if (dump_file)
6013 fprintf (dump_file, " All affected aggregate parameters were either "
6014 "removed or converted into scalars, phase done.\n");
6015 return 0;
6017 if (dump_file)
6019 fprintf (dump_file, " Aggregate replacements:");
6020 ipa_argagg_value_list avs (ts);
6021 avs.dump (dump_file);
6024 fbi.node = node;
6025 fbi.info = NULL;
6026 fbi.bb_infos = vNULL;
6027 fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
6028 fbi.param_count = param_count;
6029 fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps);
6031 vec<ipa_param_descriptor, va_gc> *descriptors = NULL;
6032 vec_safe_grow_cleared (descriptors, param_count, true);
6033 ipa_populate_param_decls (node, *descriptors);
6034 bool modified_mem_access = false;
6035 calculate_dominance_info (CDI_DOMINATORS);
6036 ipcp_modif_dom_walker walker (&fbi, descriptors, ts, &modified_mem_access);
6037 walker.walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
6038 free_dominance_info (CDI_DOMINATORS);
6039 bool cfg_changed = walker.cleanup_eh ();
6041 int i;
6042 struct ipa_bb_info *bi;
6043 FOR_EACH_VEC_ELT (fbi.bb_infos, i, bi)
6044 free_ipa_bb_info (bi);
6045 fbi.bb_infos.release ();
6047 ipcp_transformation *s = ipcp_transformation_sum->get (node);
6048 s->m_agg_values = NULL;
6049 s->bits = NULL;
6050 s->m_vr = NULL;
6052 vec_free (descriptors);
6053 if (cfg_changed)
6054 delete_unreachable_blocks_update_callgraph (node, false);
6056 return modified_mem_access ? TODO_update_ssa_only_virtuals : 0;
6060 #include "gt-ipa-prop.h"