Handle const_int in expand_single_bit_test
[official-gcc.git] / gcc / ipa-prop.cc
blobab6de9f10da9f5d1b687da12f6eb4b936e894728
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 && get_range_query (cfun)->range_of_expr (vr, arg)
2409 && !vr.undefined_p ())
2411 value_range resvr = vr;
2412 range_cast (resvr, param_type);
2413 if (!resvr.undefined_p () && !resvr.varying_p ())
2414 ipa_set_jfunc_vr (jfunc, &resvr);
2415 else
2416 gcc_assert (!jfunc->m_vr);
2418 else
2419 gcc_assert (!jfunc->m_vr);
2422 if (INTEGRAL_TYPE_P (TREE_TYPE (arg))
2423 && (TREE_CODE (arg) == SSA_NAME || TREE_CODE (arg) == INTEGER_CST))
2425 if (TREE_CODE (arg) == SSA_NAME)
2426 ipa_set_jfunc_bits (jfunc, 0,
2427 widest_int::from (get_nonzero_bits (arg),
2428 TYPE_SIGN (TREE_TYPE (arg))));
2429 else
2430 ipa_set_jfunc_bits (jfunc, wi::to_widest (arg), 0);
2432 else if (POINTER_TYPE_P (TREE_TYPE (arg)))
2434 unsigned HOST_WIDE_INT bitpos;
2435 unsigned align;
2437 get_pointer_alignment_1 (arg, &align, &bitpos);
2438 widest_int mask = wi::bit_and_not
2439 (wi::mask<widest_int> (TYPE_PRECISION (TREE_TYPE (arg)), false),
2440 align / BITS_PER_UNIT - 1);
2441 widest_int value = bitpos / BITS_PER_UNIT;
2442 ipa_set_jfunc_bits (jfunc, value, mask);
2444 else
2445 gcc_assert (!jfunc->bits);
2447 if (is_gimple_ip_invariant (arg)
2448 || (VAR_P (arg)
2449 && is_global_var (arg)
2450 && TREE_READONLY (arg)))
2451 ipa_set_jf_constant (jfunc, arg, cs);
2452 else if (!is_gimple_reg_type (TREE_TYPE (arg))
2453 && TREE_CODE (arg) == PARM_DECL)
2455 int index = ipa_get_param_decl_index (info, arg);
2457 gcc_assert (index >=0);
2458 /* Aggregate passed by value, check for pass-through, otherwise we
2459 will attempt to fill in aggregate contents later in this
2460 for cycle. */
2461 if (parm_preserved_before_stmt_p (fbi, index, call, arg))
2463 ipa_set_jf_simple_pass_through (jfunc, index, false);
2464 continue;
2467 else if (TREE_CODE (arg) == SSA_NAME)
2469 if (SSA_NAME_IS_DEFAULT_DEF (arg))
2471 int index = ipa_get_param_decl_index (info, SSA_NAME_VAR (arg));
2472 if (index >= 0)
2474 bool agg_p;
2475 agg_p = parm_ref_data_pass_through_p (fbi, index, call, arg);
2476 ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
2479 else
2481 gimple *stmt = SSA_NAME_DEF_STMT (arg);
2482 if (is_gimple_assign (stmt))
2483 compute_complex_assign_jump_func (fbi, info, jfunc,
2484 call, stmt, arg, param_type);
2485 else if (gimple_code (stmt) == GIMPLE_PHI)
2486 compute_complex_ancestor_jump_func (fbi, info, jfunc,
2487 call,
2488 as_a <gphi *> (stmt));
2492 /* If ARG is pointer, we cannot use its type to determine the type of aggregate
2493 passed (because type conversions are ignored in gimple). Usually we can
2494 safely get type from function declaration, but in case of K&R prototypes or
2495 variadic functions we can try our luck with type of the pointer passed.
2496 TODO: Since we look for actual initialization of the memory object, we may better
2497 work out the type based on the memory stores we find. */
2498 if (!param_type)
2499 param_type = TREE_TYPE (arg);
2501 if ((jfunc->type != IPA_JF_PASS_THROUGH
2502 || !ipa_get_jf_pass_through_agg_preserved (jfunc))
2503 && (jfunc->type != IPA_JF_ANCESTOR
2504 || !ipa_get_jf_ancestor_agg_preserved (jfunc))
2505 && (AGGREGATE_TYPE_P (TREE_TYPE (arg))
2506 || POINTER_TYPE_P (param_type)))
2507 determine_known_aggregate_parts (fbi, call, arg, param_type, jfunc);
2509 if (!useful_context)
2510 vec_free (args->polymorphic_call_contexts);
2513 /* Compute jump functions for all edges - both direct and indirect - outgoing
2514 from BB. */
2516 static void
2517 ipa_compute_jump_functions_for_bb (struct ipa_func_body_info *fbi, basic_block bb)
2519 struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
2520 int i;
2521 struct cgraph_edge *cs;
2523 FOR_EACH_VEC_ELT_REVERSE (bi->cg_edges, i, cs)
2525 struct cgraph_node *callee = cs->callee;
2527 if (callee)
2529 callee = callee->ultimate_alias_target ();
2530 /* We do not need to bother analyzing calls to unknown functions
2531 unless they may become known during lto/whopr. */
2532 if (!callee->definition && !flag_lto
2533 && !gimple_call_fnspec (cs->call_stmt).known_p ())
2534 continue;
2536 ipa_compute_jump_functions_for_edge (fbi, cs);
2540 /* If STMT looks like a statement loading a value from a member pointer formal
2541 parameter, return that parameter and store the offset of the field to
2542 *OFFSET_P, if it is non-NULL. Otherwise return NULL (but *OFFSET_P still
2543 might be clobbered). If USE_DELTA, then we look for a use of the delta
2544 field rather than the pfn. */
2546 static tree
2547 ipa_get_stmt_member_ptr_load_param (gimple *stmt, bool use_delta,
2548 HOST_WIDE_INT *offset_p)
2550 tree rhs, rec, ref_field, ref_offset, fld, ptr_field, delta_field;
2552 if (!gimple_assign_single_p (stmt))
2553 return NULL_TREE;
2555 rhs = gimple_assign_rhs1 (stmt);
2556 if (TREE_CODE (rhs) == COMPONENT_REF)
2558 ref_field = TREE_OPERAND (rhs, 1);
2559 rhs = TREE_OPERAND (rhs, 0);
2561 else
2562 ref_field = NULL_TREE;
2563 if (TREE_CODE (rhs) != MEM_REF)
2564 return NULL_TREE;
2565 rec = TREE_OPERAND (rhs, 0);
2566 if (TREE_CODE (rec) != ADDR_EXPR)
2567 return NULL_TREE;
2568 rec = TREE_OPERAND (rec, 0);
2569 if (TREE_CODE (rec) != PARM_DECL
2570 || !type_like_member_ptr_p (TREE_TYPE (rec), &ptr_field, &delta_field))
2571 return NULL_TREE;
2572 ref_offset = TREE_OPERAND (rhs, 1);
2574 if (use_delta)
2575 fld = delta_field;
2576 else
2577 fld = ptr_field;
2578 if (offset_p)
2579 *offset_p = int_bit_position (fld);
2581 if (ref_field)
2583 if (integer_nonzerop (ref_offset))
2584 return NULL_TREE;
2585 return ref_field == fld ? rec : NULL_TREE;
2587 else
2588 return tree_int_cst_equal (byte_position (fld), ref_offset) ? rec
2589 : NULL_TREE;
2592 /* Returns true iff T is an SSA_NAME defined by a statement. */
2594 static bool
2595 ipa_is_ssa_with_stmt_def (tree t)
2597 if (TREE_CODE (t) == SSA_NAME
2598 && !SSA_NAME_IS_DEFAULT_DEF (t))
2599 return true;
2600 else
2601 return false;
2604 /* Find the indirect call graph edge corresponding to STMT and mark it as a
2605 call to a parameter number PARAM_INDEX. NODE is the caller. Return the
2606 indirect call graph edge.
2607 If POLYMORPHIC is true record is as a destination of polymorphic call. */
2609 static struct cgraph_edge *
2610 ipa_note_param_call (struct cgraph_node *node, int param_index,
2611 gcall *stmt, bool polymorphic)
2613 struct cgraph_edge *cs;
2615 cs = node->get_edge (stmt);
2616 cs->indirect_info->param_index = param_index;
2617 cs->indirect_info->agg_contents = 0;
2618 cs->indirect_info->member_ptr = 0;
2619 cs->indirect_info->guaranteed_unmodified = 0;
2620 ipa_node_params *info = ipa_node_params_sum->get (node);
2621 ipa_set_param_used_by_indirect_call (info, param_index, true);
2622 if (cs->indirect_info->polymorphic || polymorphic)
2623 ipa_set_param_used_by_polymorphic_call (info, param_index, true);
2624 return cs;
2627 /* Analyze the CALL and examine uses of formal parameters of the caller NODE
2628 (described by INFO). PARMS_AINFO is a pointer to a vector containing
2629 intermediate information about each formal parameter. Currently it checks
2630 whether the call calls a pointer that is a formal parameter and if so, the
2631 parameter is marked with the called flag and an indirect call graph edge
2632 describing the call is created. This is very simple for ordinary pointers
2633 represented in SSA but not-so-nice when it comes to member pointers. The
2634 ugly part of this function does nothing more than trying to match the
2635 pattern of such a call. An example of such a pattern is the gimple dump
2636 below, the call is on the last line:
2638 <bb 2>:
2639 f$__delta_5 = f.__delta;
2640 f$__pfn_24 = f.__pfn;
2643 <bb 2>:
2644 f$__delta_5 = MEM[(struct *)&f];
2645 f$__pfn_24 = MEM[(struct *)&f + 4B];
2647 and a few lines below:
2649 <bb 5>
2650 D.2496_3 = (int) f$__pfn_24;
2651 D.2497_4 = D.2496_3 & 1;
2652 if (D.2497_4 != 0)
2653 goto <bb 3>;
2654 else
2655 goto <bb 4>;
2657 <bb 6>:
2658 D.2500_7 = (unsigned int) f$__delta_5;
2659 D.2501_8 = &S + D.2500_7;
2660 D.2502_9 = (int (*__vtbl_ptr_type) (void) * *) D.2501_8;
2661 D.2503_10 = *D.2502_9;
2662 D.2504_12 = f$__pfn_24 + -1;
2663 D.2505_13 = (unsigned int) D.2504_12;
2664 D.2506_14 = D.2503_10 + D.2505_13;
2665 D.2507_15 = *D.2506_14;
2666 iftmp.11_16 = (String:: *) D.2507_15;
2668 <bb 7>:
2669 # iftmp.11_1 = PHI <iftmp.11_16(3), f$__pfn_24(2)>
2670 D.2500_19 = (unsigned int) f$__delta_5;
2671 D.2508_20 = &S + D.2500_19;
2672 D.2493_21 = iftmp.11_1 (D.2508_20, 4);
2674 Such patterns are results of simple calls to a member pointer:
2676 int doprinting (int (MyString::* f)(int) const)
2678 MyString S ("somestring");
2680 return (S.*f)(4);
2683 Moreover, the function also looks for called pointers loaded from aggregates
2684 passed by value or reference. */
2686 static void
2687 ipa_analyze_indirect_call_uses (struct ipa_func_body_info *fbi, gcall *call,
2688 tree target)
2690 class ipa_node_params *info = fbi->info;
2691 HOST_WIDE_INT offset;
2692 bool by_ref;
2694 if (SSA_NAME_IS_DEFAULT_DEF (target))
2696 tree var = SSA_NAME_VAR (target);
2697 int index = ipa_get_param_decl_index (info, var);
2698 if (index >= 0)
2699 ipa_note_param_call (fbi->node, index, call, false);
2700 return;
2703 int index;
2704 gimple *def = SSA_NAME_DEF_STMT (target);
2705 bool guaranteed_unmodified;
2706 if (gimple_assign_single_p (def)
2707 && ipa_load_from_parm_agg (fbi, info->descriptors, def,
2708 gimple_assign_rhs1 (def), &index, &offset,
2709 NULL, &by_ref, &guaranteed_unmodified))
2711 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
2712 call, false);
2713 cs->indirect_info->offset = offset;
2714 cs->indirect_info->agg_contents = 1;
2715 cs->indirect_info->by_ref = by_ref;
2716 cs->indirect_info->guaranteed_unmodified = guaranteed_unmodified;
2717 return;
2720 /* Now we need to try to match the complex pattern of calling a member
2721 pointer. */
2722 if (gimple_code (def) != GIMPLE_PHI
2723 || gimple_phi_num_args (def) != 2
2724 || !POINTER_TYPE_P (TREE_TYPE (target))
2725 || TREE_CODE (TREE_TYPE (TREE_TYPE (target))) != METHOD_TYPE)
2726 return;
2728 /* First, we need to check whether one of these is a load from a member
2729 pointer that is a parameter to this function. */
2730 tree n1 = PHI_ARG_DEF (def, 0);
2731 tree n2 = PHI_ARG_DEF (def, 1);
2732 if (!ipa_is_ssa_with_stmt_def (n1) || !ipa_is_ssa_with_stmt_def (n2))
2733 return;
2734 gimple *d1 = SSA_NAME_DEF_STMT (n1);
2735 gimple *d2 = SSA_NAME_DEF_STMT (n2);
2737 tree rec;
2738 basic_block bb, virt_bb;
2739 basic_block join = gimple_bb (def);
2740 if ((rec = ipa_get_stmt_member_ptr_load_param (d1, false, &offset)))
2742 if (ipa_get_stmt_member_ptr_load_param (d2, false, NULL))
2743 return;
2745 bb = EDGE_PRED (join, 0)->src;
2746 virt_bb = gimple_bb (d2);
2748 else if ((rec = ipa_get_stmt_member_ptr_load_param (d2, false, &offset)))
2750 bb = EDGE_PRED (join, 1)->src;
2751 virt_bb = gimple_bb (d1);
2753 else
2754 return;
2756 /* Second, we need to check that the basic blocks are laid out in the way
2757 corresponding to the pattern. */
2759 if (!single_pred_p (virt_bb) || !single_succ_p (virt_bb)
2760 || single_pred (virt_bb) != bb
2761 || single_succ (virt_bb) != join)
2762 return;
2764 /* Third, let's see that the branching is done depending on the least
2765 significant bit of the pfn. */
2767 gcond *branch = safe_dyn_cast <gcond *> (*gsi_last_bb (bb));
2768 if (!branch)
2769 return;
2771 if ((gimple_cond_code (branch) != NE_EXPR
2772 && gimple_cond_code (branch) != EQ_EXPR)
2773 || !integer_zerop (gimple_cond_rhs (branch)))
2774 return;
2776 tree cond = gimple_cond_lhs (branch);
2777 if (!ipa_is_ssa_with_stmt_def (cond))
2778 return;
2780 def = SSA_NAME_DEF_STMT (cond);
2781 if (!is_gimple_assign (def)
2782 || gimple_assign_rhs_code (def) != BIT_AND_EXPR
2783 || !integer_onep (gimple_assign_rhs2 (def)))
2784 return;
2786 cond = gimple_assign_rhs1 (def);
2787 if (!ipa_is_ssa_with_stmt_def (cond))
2788 return;
2790 def = SSA_NAME_DEF_STMT (cond);
2792 if (is_gimple_assign (def)
2793 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
2795 cond = gimple_assign_rhs1 (def);
2796 if (!ipa_is_ssa_with_stmt_def (cond))
2797 return;
2798 def = SSA_NAME_DEF_STMT (cond);
2801 tree rec2;
2802 rec2 = ipa_get_stmt_member_ptr_load_param (def,
2803 (TARGET_PTRMEMFUNC_VBIT_LOCATION
2804 == ptrmemfunc_vbit_in_delta),
2805 NULL);
2806 if (rec != rec2)
2807 return;
2809 index = ipa_get_param_decl_index (info, rec);
2810 if (index >= 0
2811 && parm_preserved_before_stmt_p (fbi, index, call, rec))
2813 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
2814 call, false);
2815 cs->indirect_info->offset = offset;
2816 cs->indirect_info->agg_contents = 1;
2817 cs->indirect_info->member_ptr = 1;
2818 cs->indirect_info->guaranteed_unmodified = 1;
2821 return;
2824 /* Analyze a CALL to an OBJ_TYPE_REF which is passed in TARGET and if the
2825 object referenced in the expression is a formal parameter of the caller
2826 FBI->node (described by FBI->info), create a call note for the
2827 statement. */
2829 static void
2830 ipa_analyze_virtual_call_uses (struct ipa_func_body_info *fbi,
2831 gcall *call, tree target)
2833 tree obj = OBJ_TYPE_REF_OBJECT (target);
2834 int index;
2835 HOST_WIDE_INT anc_offset;
2837 if (!flag_devirtualize)
2838 return;
2840 if (TREE_CODE (obj) != SSA_NAME)
2841 return;
2843 class ipa_node_params *info = fbi->info;
2844 if (SSA_NAME_IS_DEFAULT_DEF (obj))
2846 if (TREE_CODE (SSA_NAME_VAR (obj)) != PARM_DECL)
2847 return;
2849 anc_offset = 0;
2850 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (obj));
2851 gcc_assert (index >= 0);
2852 if (detect_type_change_ssa (fbi, obj, obj_type_ref_class (target),
2853 call))
2854 return;
2856 else
2858 gimple *stmt = SSA_NAME_DEF_STMT (obj);
2859 tree expr;
2861 expr = get_ancestor_addr_info (stmt, &obj, &anc_offset);
2862 if (!expr)
2863 return;
2864 index = ipa_get_param_decl_index (info,
2865 SSA_NAME_VAR (TREE_OPERAND (expr, 0)));
2866 gcc_assert (index >= 0);
2867 if (detect_type_change (fbi, obj, expr, obj_type_ref_class (target),
2868 call, anc_offset))
2869 return;
2872 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
2873 call, true);
2874 class cgraph_indirect_call_info *ii = cs->indirect_info;
2875 ii->offset = anc_offset;
2876 ii->otr_token = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target));
2877 ii->otr_type = obj_type_ref_class (target);
2878 ii->polymorphic = 1;
2881 /* Analyze a call statement CALL whether and how it utilizes formal parameters
2882 of the caller (described by INFO). PARMS_AINFO is a pointer to a vector
2883 containing intermediate information about each formal parameter. */
2885 static void
2886 ipa_analyze_call_uses (struct ipa_func_body_info *fbi, gcall *call)
2888 tree target = gimple_call_fn (call);
2890 if (!target
2891 || (TREE_CODE (target) != SSA_NAME
2892 && !virtual_method_call_p (target)))
2893 return;
2895 struct cgraph_edge *cs = fbi->node->get_edge (call);
2896 /* If we previously turned the call into a direct call, there is
2897 no need to analyze. */
2898 if (cs && !cs->indirect_unknown_callee)
2899 return;
2901 if (cs->indirect_info->polymorphic && flag_devirtualize)
2903 tree instance;
2904 tree target = gimple_call_fn (call);
2905 ipa_polymorphic_call_context context (current_function_decl,
2906 target, call, &instance);
2908 gcc_checking_assert (cs->indirect_info->otr_type
2909 == obj_type_ref_class (target));
2910 gcc_checking_assert (cs->indirect_info->otr_token
2911 == tree_to_shwi (OBJ_TYPE_REF_TOKEN (target)));
2913 cs->indirect_info->vptr_changed
2914 = !context.get_dynamic_type (instance,
2915 OBJ_TYPE_REF_OBJECT (target),
2916 obj_type_ref_class (target), call,
2917 &fbi->aa_walk_budget);
2918 cs->indirect_info->context = context;
2921 if (TREE_CODE (target) == SSA_NAME)
2922 ipa_analyze_indirect_call_uses (fbi, call, target);
2923 else if (virtual_method_call_p (target))
2924 ipa_analyze_virtual_call_uses (fbi, call, target);
2928 /* Analyze the call statement STMT with respect to formal parameters (described
2929 in INFO) of caller given by FBI->NODE. Currently it only checks whether
2930 formal parameters are called. */
2932 static void
2933 ipa_analyze_stmt_uses (struct ipa_func_body_info *fbi, gimple *stmt)
2935 if (is_gimple_call (stmt))
2936 ipa_analyze_call_uses (fbi, as_a <gcall *> (stmt));
2939 /* Callback of walk_stmt_load_store_addr_ops for the visit_load.
2940 If OP is a parameter declaration, mark it as used in the info structure
2941 passed in DATA. */
2943 static bool
2944 visit_ref_for_mod_analysis (gimple *, tree op, tree, void *data)
2946 class ipa_node_params *info = (class ipa_node_params *) data;
2948 op = get_base_address (op);
2949 if (op
2950 && TREE_CODE (op) == PARM_DECL)
2952 int index = ipa_get_param_decl_index (info, op);
2953 gcc_assert (index >= 0);
2954 ipa_set_param_used (info, index, true);
2957 return false;
2960 /* Scan the statements in BB and inspect the uses of formal parameters. Store
2961 the findings in various structures of the associated ipa_node_params
2962 structure, such as parameter flags, notes etc. FBI holds various data about
2963 the function being analyzed. */
2965 static void
2966 ipa_analyze_params_uses_in_bb (struct ipa_func_body_info *fbi, basic_block bb)
2968 gimple_stmt_iterator gsi;
2969 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2971 gimple *stmt = gsi_stmt (gsi);
2973 if (is_gimple_debug (stmt))
2974 continue;
2976 ipa_analyze_stmt_uses (fbi, stmt);
2977 walk_stmt_load_store_addr_ops (stmt, fbi->info,
2978 visit_ref_for_mod_analysis,
2979 visit_ref_for_mod_analysis,
2980 visit_ref_for_mod_analysis);
2982 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2983 walk_stmt_load_store_addr_ops (gsi_stmt (gsi), fbi->info,
2984 visit_ref_for_mod_analysis,
2985 visit_ref_for_mod_analysis,
2986 visit_ref_for_mod_analysis);
2989 /* Return true EXPR is a load from a dereference of SSA_NAME NAME. */
2991 static bool
2992 load_from_dereferenced_name (tree expr, tree name)
2994 tree base = get_base_address (expr);
2995 return (TREE_CODE (base) == MEM_REF
2996 && TREE_OPERAND (base, 0) == name);
2999 /* Calculate controlled uses of parameters of NODE. */
3001 static void
3002 ipa_analyze_controlled_uses (struct cgraph_node *node)
3004 ipa_node_params *info = ipa_node_params_sum->get (node);
3006 for (int i = 0; i < ipa_get_param_count (info); i++)
3008 tree parm = ipa_get_param (info, i);
3009 int call_uses = 0;
3010 bool load_dereferenced = false;
3012 /* For SSA regs see if parameter is used. For non-SSA we compute
3013 the flag during modification analysis. */
3014 if (is_gimple_reg (parm))
3016 tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl),
3017 parm);
3018 if (ddef && !has_zero_uses (ddef))
3020 imm_use_iterator imm_iter;
3021 gimple *stmt;
3023 ipa_set_param_used (info, i, true);
3024 FOR_EACH_IMM_USE_STMT (stmt, imm_iter, ddef)
3026 if (is_gimple_debug (stmt))
3027 continue;
3029 int all_stmt_uses = 0;
3030 use_operand_p use_p;
3031 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
3032 all_stmt_uses++;
3034 if (is_gimple_call (stmt))
3036 if (gimple_call_internal_p (stmt))
3038 call_uses = IPA_UNDESCRIBED_USE;
3039 break;
3041 int recognized_stmt_uses;
3042 if (gimple_call_fn (stmt) == ddef)
3043 recognized_stmt_uses = 1;
3044 else
3045 recognized_stmt_uses = 0;
3046 unsigned arg_count = gimple_call_num_args (stmt);
3047 for (unsigned i = 0; i < arg_count; i++)
3049 tree arg = gimple_call_arg (stmt, i);
3050 if (arg == ddef)
3051 recognized_stmt_uses++;
3052 else if (load_from_dereferenced_name (arg, ddef))
3054 load_dereferenced = true;
3055 recognized_stmt_uses++;
3059 if (recognized_stmt_uses != all_stmt_uses)
3061 call_uses = IPA_UNDESCRIBED_USE;
3062 break;
3064 if (call_uses >= 0)
3065 call_uses += all_stmt_uses;
3067 else if (gimple_assign_single_p (stmt))
3069 tree rhs = gimple_assign_rhs1 (stmt);
3070 if (all_stmt_uses != 1
3071 || !load_from_dereferenced_name (rhs, ddef))
3073 call_uses = IPA_UNDESCRIBED_USE;
3074 break;
3076 load_dereferenced = true;
3078 else
3080 call_uses = IPA_UNDESCRIBED_USE;
3081 break;
3085 else
3086 call_uses = 0;
3088 else
3089 call_uses = IPA_UNDESCRIBED_USE;
3090 ipa_set_controlled_uses (info, i, call_uses);
3091 ipa_set_param_load_dereferenced (info, i, load_dereferenced);
3095 /* Free stuff in BI. */
3097 static void
3098 free_ipa_bb_info (struct ipa_bb_info *bi)
3100 bi->cg_edges.release ();
3101 bi->param_aa_statuses.release ();
3104 /* Dominator walker driving the analysis. */
3106 class analysis_dom_walker : public dom_walker
3108 public:
3109 analysis_dom_walker (struct ipa_func_body_info *fbi)
3110 : dom_walker (CDI_DOMINATORS), m_fbi (fbi) {}
3112 edge before_dom_children (basic_block) final override;
3114 private:
3115 struct ipa_func_body_info *m_fbi;
3118 edge
3119 analysis_dom_walker::before_dom_children (basic_block bb)
3121 ipa_analyze_params_uses_in_bb (m_fbi, bb);
3122 ipa_compute_jump_functions_for_bb (m_fbi, bb);
3123 return NULL;
3126 /* Release body info FBI. */
3128 void
3129 ipa_release_body_info (struct ipa_func_body_info *fbi)
3131 int i;
3132 struct ipa_bb_info *bi;
3134 FOR_EACH_VEC_ELT (fbi->bb_infos, i, bi)
3135 free_ipa_bb_info (bi);
3136 fbi->bb_infos.release ();
3139 /* Initialize the array describing properties of formal parameters
3140 of NODE, analyze their uses and compute jump functions associated
3141 with actual arguments of calls from within NODE. */
3143 void
3144 ipa_analyze_node (struct cgraph_node *node)
3146 struct ipa_func_body_info fbi;
3147 class ipa_node_params *info;
3149 ipa_check_create_node_params ();
3150 ipa_check_create_edge_args ();
3151 info = ipa_node_params_sum->get_create (node);
3153 if (info->analysis_done)
3154 return;
3155 info->analysis_done = 1;
3157 if (ipa_func_spec_opts_forbid_analysis_p (node)
3158 || (count_formal_params (node->decl)
3159 >= (1 << IPA_PROP_ARG_INDEX_LIMIT_BITS)))
3161 gcc_assert (!ipa_get_param_count (info));
3162 return;
3165 struct function *func = DECL_STRUCT_FUNCTION (node->decl);
3166 push_cfun (func);
3167 calculate_dominance_info (CDI_DOMINATORS);
3168 ipa_initialize_node_params (node);
3169 ipa_analyze_controlled_uses (node);
3171 fbi.node = node;
3172 fbi.info = info;
3173 fbi.bb_infos = vNULL;
3174 fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
3175 fbi.param_count = ipa_get_param_count (info);
3176 fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps);
3178 for (struct cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
3180 ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
3181 bi->cg_edges.safe_push (cs);
3184 for (struct cgraph_edge *cs = node->indirect_calls; cs; cs = cs->next_callee)
3186 ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
3187 bi->cg_edges.safe_push (cs);
3190 analysis_dom_walker (&fbi).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
3192 ipa_release_body_info (&fbi);
3193 free_dominance_info (CDI_DOMINATORS);
3194 pop_cfun ();
3197 /* Update the jump functions associated with call graph edge E when the call
3198 graph edge CS is being inlined, assuming that E->caller is already (possibly
3199 indirectly) inlined into CS->callee and that E has not been inlined. */
3201 static void
3202 update_jump_functions_after_inlining (struct cgraph_edge *cs,
3203 struct cgraph_edge *e)
3205 ipa_edge_args *top = ipa_edge_args_sum->get (cs);
3206 ipa_edge_args *args = ipa_edge_args_sum->get (e);
3207 if (!args)
3208 return;
3209 int count = ipa_get_cs_argument_count (args);
3210 int i;
3212 for (i = 0; i < count; i++)
3214 struct ipa_jump_func *dst = ipa_get_ith_jump_func (args, i);
3215 class ipa_polymorphic_call_context *dst_ctx
3216 = ipa_get_ith_polymorhic_call_context (args, i);
3218 if (dst->agg.items)
3220 struct ipa_agg_jf_item *item;
3221 int j;
3223 FOR_EACH_VEC_ELT (*dst->agg.items, j, item)
3225 int dst_fid;
3226 struct ipa_jump_func *src;
3228 if (item->jftype != IPA_JF_PASS_THROUGH
3229 && item->jftype != IPA_JF_LOAD_AGG)
3230 continue;
3232 dst_fid = item->value.pass_through.formal_id;
3233 if (!top || dst_fid >= ipa_get_cs_argument_count (top))
3235 item->jftype = IPA_JF_UNKNOWN;
3236 continue;
3239 item->value.pass_through.formal_id = -1;
3240 src = ipa_get_ith_jump_func (top, dst_fid);
3241 if (src->type == IPA_JF_CONST)
3243 if (item->jftype == IPA_JF_PASS_THROUGH
3244 && item->value.pass_through.operation == NOP_EXPR)
3246 item->jftype = IPA_JF_CONST;
3247 item->value.constant = src->value.constant.value;
3248 continue;
3251 else if (src->type == IPA_JF_PASS_THROUGH
3252 && src->value.pass_through.operation == NOP_EXPR)
3254 if (item->jftype == IPA_JF_PASS_THROUGH
3255 || !item->value.load_agg.by_ref
3256 || src->value.pass_through.agg_preserved)
3257 item->value.pass_through.formal_id
3258 = src->value.pass_through.formal_id;
3260 else if (src->type == IPA_JF_ANCESTOR)
3262 if (item->jftype == IPA_JF_PASS_THROUGH)
3264 if (!src->value.ancestor.offset)
3265 item->value.pass_through.formal_id
3266 = src->value.ancestor.formal_id;
3268 else if (src->value.ancestor.agg_preserved)
3270 gcc_checking_assert (item->value.load_agg.by_ref);
3272 item->value.pass_through.formal_id
3273 = src->value.ancestor.formal_id;
3274 item->value.load_agg.offset
3275 += src->value.ancestor.offset;
3279 if (item->value.pass_through.formal_id < 0)
3280 item->jftype = IPA_JF_UNKNOWN;
3284 if (!top)
3286 ipa_set_jf_unknown (dst);
3287 continue;
3290 if (dst->type == IPA_JF_ANCESTOR)
3292 struct ipa_jump_func *src;
3293 int dst_fid = dst->value.ancestor.formal_id;
3294 class ipa_polymorphic_call_context *src_ctx
3295 = ipa_get_ith_polymorhic_call_context (top, dst_fid);
3297 /* Variable number of arguments can cause havoc if we try to access
3298 one that does not exist in the inlined edge. So make sure we
3299 don't. */
3300 if (dst_fid >= ipa_get_cs_argument_count (top))
3302 ipa_set_jf_unknown (dst);
3303 continue;
3306 src = ipa_get_ith_jump_func (top, dst_fid);
3308 if (src_ctx && !src_ctx->useless_p ())
3310 class ipa_polymorphic_call_context ctx = *src_ctx;
3312 /* TODO: Make type preserved safe WRT contexts. */
3313 if (!ipa_get_jf_ancestor_type_preserved (dst))
3314 ctx.possible_dynamic_type_change (e->in_polymorphic_cdtor);
3315 ctx.offset_by (dst->value.ancestor.offset);
3316 if (!ctx.useless_p ())
3318 if (!dst_ctx)
3320 vec_safe_grow_cleared (args->polymorphic_call_contexts,
3321 count, true);
3322 dst_ctx = ipa_get_ith_polymorhic_call_context (args, i);
3325 dst_ctx->combine_with (ctx);
3329 /* Parameter and argument in ancestor jump function must be pointer
3330 type, which means access to aggregate must be by-reference. */
3331 gcc_assert (!src->agg.items || src->agg.by_ref);
3333 if (src->agg.items && dst->value.ancestor.agg_preserved)
3335 struct ipa_agg_jf_item *item;
3336 int j;
3338 /* Currently we do not produce clobber aggregate jump functions,
3339 replace with merging when we do. */
3340 gcc_assert (!dst->agg.items);
3342 dst->agg.items = vec_safe_copy (src->agg.items);
3343 dst->agg.by_ref = src->agg.by_ref;
3344 FOR_EACH_VEC_SAFE_ELT (dst->agg.items, j, item)
3345 item->offset -= dst->value.ancestor.offset;
3348 if (src->type == IPA_JF_PASS_THROUGH
3349 && src->value.pass_through.operation == NOP_EXPR)
3351 dst->value.ancestor.formal_id = src->value.pass_through.formal_id;
3352 dst->value.ancestor.agg_preserved &=
3353 src->value.pass_through.agg_preserved;
3355 else if (src->type == IPA_JF_ANCESTOR)
3357 dst->value.ancestor.formal_id = src->value.ancestor.formal_id;
3358 dst->value.ancestor.offset += src->value.ancestor.offset;
3359 dst->value.ancestor.agg_preserved &=
3360 src->value.ancestor.agg_preserved;
3361 dst->value.ancestor.keep_null |= src->value.ancestor.keep_null;
3363 else
3364 ipa_set_jf_unknown (dst);
3366 else if (dst->type == IPA_JF_PASS_THROUGH)
3368 struct ipa_jump_func *src;
3369 /* We must check range due to calls with variable number of arguments
3370 and we cannot combine jump functions with operations. */
3371 if (dst->value.pass_through.operation == NOP_EXPR
3372 && (top && dst->value.pass_through.formal_id
3373 < ipa_get_cs_argument_count (top)))
3375 int dst_fid = dst->value.pass_through.formal_id;
3376 src = ipa_get_ith_jump_func (top, dst_fid);
3377 bool dst_agg_p = ipa_get_jf_pass_through_agg_preserved (dst);
3378 class ipa_polymorphic_call_context *src_ctx
3379 = ipa_get_ith_polymorhic_call_context (top, dst_fid);
3381 if (src_ctx && !src_ctx->useless_p ())
3383 class ipa_polymorphic_call_context ctx = *src_ctx;
3385 /* TODO: Make type preserved safe WRT contexts. */
3386 if (!ipa_get_jf_pass_through_type_preserved (dst))
3387 ctx.possible_dynamic_type_change (e->in_polymorphic_cdtor);
3388 if (!ctx.useless_p ())
3390 if (!dst_ctx)
3392 vec_safe_grow_cleared (args->polymorphic_call_contexts,
3393 count, true);
3394 dst_ctx = ipa_get_ith_polymorhic_call_context (args, i);
3396 dst_ctx->combine_with (ctx);
3399 switch (src->type)
3401 case IPA_JF_UNKNOWN:
3402 ipa_set_jf_unknown (dst);
3403 break;
3404 case IPA_JF_CONST:
3406 bool rd = ipa_get_jf_pass_through_refdesc_decremented (dst);
3407 ipa_set_jf_cst_copy (dst, src);
3408 if (rd)
3409 ipa_zap_jf_refdesc (dst);
3412 break;
3414 case IPA_JF_PASS_THROUGH:
3416 int formal_id = ipa_get_jf_pass_through_formal_id (src);
3417 enum tree_code operation;
3418 operation = ipa_get_jf_pass_through_operation (src);
3420 if (operation == NOP_EXPR)
3422 bool agg_p;
3423 agg_p = dst_agg_p
3424 && ipa_get_jf_pass_through_agg_preserved (src);
3425 ipa_set_jf_simple_pass_through (dst, formal_id, agg_p);
3427 else if (TREE_CODE_CLASS (operation) == tcc_unary)
3428 ipa_set_jf_unary_pass_through (dst, formal_id, operation);
3429 else
3431 tree operand = ipa_get_jf_pass_through_operand (src);
3432 ipa_set_jf_arith_pass_through (dst, formal_id, operand,
3433 operation);
3435 break;
3437 case IPA_JF_ANCESTOR:
3439 bool agg_p;
3440 agg_p = dst_agg_p
3441 && ipa_get_jf_ancestor_agg_preserved (src);
3442 ipa_set_ancestor_jf (dst,
3443 ipa_get_jf_ancestor_offset (src),
3444 ipa_get_jf_ancestor_formal_id (src),
3445 agg_p,
3446 ipa_get_jf_ancestor_keep_null (src));
3447 break;
3449 default:
3450 gcc_unreachable ();
3453 if (src->agg.items
3454 && (dst_agg_p || !src->agg.by_ref))
3456 /* Currently we do not produce clobber aggregate jump
3457 functions, replace with merging when we do. */
3458 gcc_assert (!dst->agg.items);
3460 dst->agg.by_ref = src->agg.by_ref;
3461 dst->agg.items = vec_safe_copy (src->agg.items);
3464 else
3465 ipa_set_jf_unknown (dst);
3470 /* If TARGET is an addr_expr of a function declaration, make it the
3471 (SPECULATIVE)destination of an indirect edge IE and return the edge.
3472 Otherwise, return NULL. */
3474 struct cgraph_edge *
3475 ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
3476 bool speculative)
3478 struct cgraph_node *callee;
3479 bool unreachable = false;
3481 if (TREE_CODE (target) == ADDR_EXPR)
3482 target = TREE_OPERAND (target, 0);
3483 if (TREE_CODE (target) != FUNCTION_DECL)
3485 target = canonicalize_constructor_val (target, NULL);
3486 if (!target || TREE_CODE (target) != FUNCTION_DECL)
3488 /* Member pointer call that goes through a VMT lookup. */
3489 if (ie->indirect_info->member_ptr
3490 /* Or if target is not an invariant expression and we do not
3491 know if it will evaulate to function at runtime.
3492 This can happen when folding through &VAR, where &VAR
3493 is IP invariant, but VAR itself is not.
3495 TODO: Revisit this when GCC 5 is branched. It seems that
3496 member_ptr check is not needed and that we may try to fold
3497 the expression and see if VAR is readonly. */
3498 || !is_gimple_ip_invariant (target))
3500 if (dump_enabled_p ())
3502 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
3503 "discovered direct call non-invariant %s\n",
3504 ie->caller->dump_name ());
3506 return NULL;
3510 if (dump_enabled_p ())
3512 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
3513 "discovered direct call to non-function in %s, "
3514 "making it __builtin_unreachable\n",
3515 ie->caller->dump_name ());
3518 target = builtin_decl_unreachable ();
3519 callee = cgraph_node::get_create (target);
3520 unreachable = true;
3522 else
3523 callee = cgraph_node::get (target);
3525 else
3526 callee = cgraph_node::get (target);
3528 /* Because may-edges are not explicitely represented and vtable may be external,
3529 we may create the first reference to the object in the unit. */
3530 if (!callee || callee->inlined_to)
3533 /* We are better to ensure we can refer to it.
3534 In the case of static functions we are out of luck, since we already
3535 removed its body. In the case of public functions we may or may
3536 not introduce the reference. */
3537 if (!canonicalize_constructor_val (target, NULL)
3538 || !TREE_PUBLIC (target))
3540 if (dump_file)
3541 fprintf (dump_file, "ipa-prop: Discovered call to a known target "
3542 "(%s -> %s) but cannot refer to it. Giving up.\n",
3543 ie->caller->dump_name (),
3544 ie->callee->dump_name ());
3545 return NULL;
3547 callee = cgraph_node::get_create (target);
3550 /* If the edge is already speculated. */
3551 if (speculative && ie->speculative)
3553 if (dump_file)
3555 cgraph_edge *e2 = ie->speculative_call_for_target (callee);
3556 if (!e2)
3558 if (dump_file)
3559 fprintf (dump_file, "ipa-prop: Discovered call to a "
3560 "speculative target (%s -> %s) but the call is "
3561 "already speculated to different target. "
3562 "Giving up.\n",
3563 ie->caller->dump_name (), callee->dump_name ());
3565 else
3567 if (dump_file)
3568 fprintf (dump_file,
3569 "ipa-prop: Discovered call to a speculative target "
3570 "(%s -> %s) this agree with previous speculation.\n",
3571 ie->caller->dump_name (), callee->dump_name ());
3574 return NULL;
3577 if (!dbg_cnt (devirt))
3578 return NULL;
3580 ipa_check_create_node_params ();
3582 /* We cannot make edges to inline clones. It is bug that someone removed
3583 the cgraph node too early. */
3584 gcc_assert (!callee->inlined_to);
3586 if (dump_file && !unreachable)
3588 fprintf (dump_file, "ipa-prop: Discovered %s call to a %s target "
3589 "(%s -> %s), for stmt ",
3590 ie->indirect_info->polymorphic ? "a virtual" : "an indirect",
3591 speculative ? "speculative" : "known",
3592 ie->caller->dump_name (),
3593 callee->dump_name ());
3594 if (ie->call_stmt)
3595 print_gimple_stmt (dump_file, ie->call_stmt, 2, TDF_SLIM);
3596 else
3597 fprintf (dump_file, "with uid %i\n", ie->lto_stmt_uid);
3599 if (dump_enabled_p ())
3601 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
3602 "converting indirect call in %s to direct call to %s\n",
3603 ie->caller->dump_name (), callee->dump_name ());
3605 if (!speculative)
3607 struct cgraph_edge *orig = ie;
3608 ie = cgraph_edge::make_direct (ie, callee);
3609 /* If we resolved speculative edge the cost is already up to date
3610 for direct call (adjusted by inline_edge_duplication_hook). */
3611 if (ie == orig)
3613 ipa_call_summary *es = ipa_call_summaries->get (ie);
3614 es->call_stmt_size -= (eni_size_weights.indirect_call_cost
3615 - eni_size_weights.call_cost);
3616 es->call_stmt_time -= (eni_time_weights.indirect_call_cost
3617 - eni_time_weights.call_cost);
3620 else
3622 if (!callee->can_be_discarded_p ())
3624 cgraph_node *alias;
3625 alias = dyn_cast<cgraph_node *> (callee->noninterposable_alias ());
3626 if (alias)
3627 callee = alias;
3629 /* make_speculative will update ie's cost to direct call cost. */
3630 ie = ie->make_speculative
3631 (callee, ie->count.apply_scale (8, 10));
3634 return ie;
3637 /* Attempt to locate an interprocedural constant at a given REQ_OFFSET in
3638 CONSTRUCTOR and return it. Return NULL if the search fails for some
3639 reason. */
3641 static tree
3642 find_constructor_constant_at_offset (tree constructor, HOST_WIDE_INT req_offset)
3644 tree type = TREE_TYPE (constructor);
3645 if (TREE_CODE (type) != ARRAY_TYPE
3646 && TREE_CODE (type) != RECORD_TYPE)
3647 return NULL;
3649 unsigned ix;
3650 tree index, val;
3651 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (constructor), ix, index, val)
3653 HOST_WIDE_INT elt_offset;
3654 if (TREE_CODE (type) == ARRAY_TYPE)
3656 offset_int off;
3657 tree unit_size = TYPE_SIZE_UNIT (TREE_TYPE (type));
3658 gcc_assert (TREE_CODE (unit_size) == INTEGER_CST);
3660 if (index)
3662 if (TREE_CODE (index) == RANGE_EXPR)
3663 off = wi::to_offset (TREE_OPERAND (index, 0));
3664 else
3665 off = wi::to_offset (index);
3666 if (TYPE_DOMAIN (type) && TYPE_MIN_VALUE (TYPE_DOMAIN (type)))
3668 tree low_bound = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
3669 gcc_assert (TREE_CODE (unit_size) == INTEGER_CST);
3670 off = wi::sext (off - wi::to_offset (low_bound),
3671 TYPE_PRECISION (TREE_TYPE (index)));
3673 off *= wi::to_offset (unit_size);
3674 /* ??? Handle more than just the first index of a
3675 RANGE_EXPR. */
3677 else
3678 off = wi::to_offset (unit_size) * ix;
3680 off = wi::lshift (off, LOG2_BITS_PER_UNIT);
3681 if (!wi::fits_shwi_p (off) || wi::neg_p (off))
3682 continue;
3683 elt_offset = off.to_shwi ();
3685 else if (TREE_CODE (type) == RECORD_TYPE)
3687 gcc_checking_assert (index && TREE_CODE (index) == FIELD_DECL);
3688 if (DECL_BIT_FIELD (index))
3689 continue;
3690 elt_offset = int_bit_position (index);
3692 else
3693 gcc_unreachable ();
3695 if (elt_offset > req_offset)
3696 return NULL;
3698 if (TREE_CODE (val) == CONSTRUCTOR)
3699 return find_constructor_constant_at_offset (val,
3700 req_offset - elt_offset);
3702 if (elt_offset == req_offset
3703 && is_gimple_reg_type (TREE_TYPE (val))
3704 && is_gimple_ip_invariant (val))
3705 return val;
3707 return NULL;
3710 /* Check whether SCALAR could be used to look up an aggregate interprocedural
3711 invariant from a static constructor and if so, return it. Otherwise return
3712 NULL. */
3714 tree
3715 ipa_find_agg_cst_from_init (tree scalar, HOST_WIDE_INT offset, bool by_ref)
3717 if (by_ref)
3719 if (TREE_CODE (scalar) != ADDR_EXPR)
3720 return NULL;
3721 scalar = TREE_OPERAND (scalar, 0);
3724 if (!VAR_P (scalar)
3725 || !is_global_var (scalar)
3726 || !TREE_READONLY (scalar)
3727 || !DECL_INITIAL (scalar)
3728 || TREE_CODE (DECL_INITIAL (scalar)) != CONSTRUCTOR)
3729 return NULL;
3731 return find_constructor_constant_at_offset (DECL_INITIAL (scalar), offset);
3734 /* Retrieve value from AGG_JFUNC for the given OFFSET or return NULL if there
3735 is none. BY_REF specifies whether the value has to be passed by reference
3736 or by value. */
3738 static tree
3739 ipa_find_agg_cst_from_jfunc_items (struct ipa_agg_jump_function *agg_jfunc,
3740 ipa_node_params *src_info,
3741 cgraph_node *src_node,
3742 HOST_WIDE_INT offset, bool by_ref)
3744 if (by_ref != agg_jfunc->by_ref)
3745 return NULL_TREE;
3747 for (const ipa_agg_jf_item &item : agg_jfunc->items)
3748 if (item.offset == offset)
3749 return ipa_agg_value_from_jfunc (src_info, src_node, &item);
3751 return NULL_TREE;
3754 /* Remove a reference to SYMBOL from the list of references of a node given by
3755 reference description RDESC. Return true if the reference has been
3756 successfully found and removed. */
3758 static bool
3759 remove_described_reference (symtab_node *symbol, struct ipa_cst_ref_desc *rdesc)
3761 struct ipa_ref *to_del;
3762 struct cgraph_edge *origin;
3764 origin = rdesc->cs;
3765 if (!origin)
3766 return false;
3767 to_del = origin->caller->find_reference (symbol, origin->call_stmt,
3768 origin->lto_stmt_uid, IPA_REF_ADDR);
3769 if (!to_del)
3770 return false;
3772 to_del->remove_reference ();
3773 if (dump_file)
3774 fprintf (dump_file, "ipa-prop: Removed a reference from %s to %s.\n",
3775 origin->caller->dump_name (), symbol->dump_name ());
3776 return true;
3779 /* If JFUNC has a reference description with refcount different from
3780 IPA_UNDESCRIBED_USE, return the reference description, otherwise return
3781 NULL. JFUNC must be a constant jump function. */
3783 static struct ipa_cst_ref_desc *
3784 jfunc_rdesc_usable (struct ipa_jump_func *jfunc)
3786 struct ipa_cst_ref_desc *rdesc = ipa_get_jf_constant_rdesc (jfunc);
3787 if (rdesc && rdesc->refcount != IPA_UNDESCRIBED_USE)
3788 return rdesc;
3789 else
3790 return NULL;
3793 /* If the value of constant jump function JFUNC is an address of a function
3794 declaration, return the associated call graph node. Otherwise return
3795 NULL. */
3797 static symtab_node *
3798 symtab_node_for_jfunc (struct ipa_jump_func *jfunc)
3800 gcc_checking_assert (jfunc->type == IPA_JF_CONST);
3801 tree cst = ipa_get_jf_constant (jfunc);
3802 if (TREE_CODE (cst) != ADDR_EXPR
3803 || (TREE_CODE (TREE_OPERAND (cst, 0)) != FUNCTION_DECL
3804 && TREE_CODE (TREE_OPERAND (cst, 0)) != VAR_DECL))
3805 return NULL;
3807 return symtab_node::get (TREE_OPERAND (cst, 0));
3811 /* If JFUNC is a constant jump function with a usable rdesc, decrement its
3812 refcount and if it hits zero, remove reference to SYMBOL from the caller of
3813 the edge specified in the rdesc. Return false if either the symbol or the
3814 reference could not be found, otherwise return true. */
3816 static bool
3817 try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc)
3819 struct ipa_cst_ref_desc *rdesc;
3820 if (jfunc->type == IPA_JF_CONST
3821 && (rdesc = jfunc_rdesc_usable (jfunc))
3822 && --rdesc->refcount == 0)
3824 symtab_node *symbol = symtab_node_for_jfunc (jfunc);
3825 if (!symbol)
3826 return false;
3828 return remove_described_reference (symbol, rdesc);
3830 return true;
3833 /* Try to find a destination for indirect edge IE that corresponds to a simple
3834 call or a call of a member function pointer and where the destination is a
3835 pointer formal parameter described by jump function JFUNC. TARGET_TYPE is
3836 the type of the parameter to which the result of JFUNC is passed. If it can
3837 be determined, return the newly direct edge, otherwise return NULL.
3838 NEW_ROOT and NEW_ROOT_INFO is the node and its info that JFUNC lattices are
3839 relative to. */
3841 static struct cgraph_edge *
3842 try_make_edge_direct_simple_call (struct cgraph_edge *ie,
3843 struct ipa_jump_func *jfunc, tree target_type,
3844 struct cgraph_node *new_root,
3845 class ipa_node_params *new_root_info)
3847 struct cgraph_edge *cs;
3848 tree target = NULL_TREE;
3849 bool agg_contents = ie->indirect_info->agg_contents;
3850 tree scalar = ipa_value_from_jfunc (new_root_info, jfunc, target_type);
3851 if (agg_contents)
3853 if (scalar)
3854 target = ipa_find_agg_cst_from_init (scalar, ie->indirect_info->offset,
3855 ie->indirect_info->by_ref);
3856 if (!target && ie->indirect_info->guaranteed_unmodified)
3857 target = ipa_find_agg_cst_from_jfunc_items (&jfunc->agg, new_root_info,
3858 new_root,
3859 ie->indirect_info->offset,
3860 ie->indirect_info->by_ref);
3862 else
3863 target = scalar;
3864 if (!target)
3865 return NULL;
3866 cs = ipa_make_edge_direct_to_target (ie, target);
3868 if (cs && !agg_contents)
3870 bool ok;
3871 gcc_checking_assert (cs->callee
3872 && (cs != ie
3873 || jfunc->type != IPA_JF_CONST
3874 || !symtab_node_for_jfunc (jfunc)
3875 || cs->callee == symtab_node_for_jfunc (jfunc)));
3876 ok = try_decrement_rdesc_refcount (jfunc);
3877 gcc_checking_assert (ok);
3880 return cs;
3883 /* Return the target to be used in cases of impossible devirtualization. IE
3884 and target (the latter can be NULL) are dumped when dumping is enabled. */
3886 tree
3887 ipa_impossible_devirt_target (struct cgraph_edge *ie, tree target)
3889 if (dump_file)
3891 if (target)
3892 fprintf (dump_file,
3893 "Type inconsistent devirtualization: %s->%s\n",
3894 ie->caller->dump_name (),
3895 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (target)));
3896 else
3897 fprintf (dump_file,
3898 "No devirtualization target in %s\n",
3899 ie->caller->dump_name ());
3901 tree new_target = builtin_decl_unreachable ();
3902 cgraph_node::get_create (new_target);
3903 return new_target;
3906 /* Try to find a destination for indirect edge IE that corresponds to a virtual
3907 call based on a formal parameter which is described by jump function JFUNC
3908 and if it can be determined, make it direct and return the direct edge.
3909 Otherwise, return NULL. CTX describes the polymorphic context that the
3910 parameter the call is based on brings along with it. NEW_ROOT and
3911 NEW_ROOT_INFO is the node and its info that JFUNC lattices are relative
3912 to. */
3914 static struct cgraph_edge *
3915 try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
3916 struct ipa_jump_func *jfunc,
3917 class ipa_polymorphic_call_context ctx,
3918 struct cgraph_node *new_root,
3919 class ipa_node_params *new_root_info)
3921 tree target = NULL;
3922 bool speculative = false;
3924 if (!opt_for_fn (ie->caller->decl, flag_devirtualize))
3925 return NULL;
3927 gcc_assert (!ie->indirect_info->by_ref);
3929 /* Try to do lookup via known virtual table pointer value. */
3930 if (!ie->indirect_info->vptr_changed
3931 || opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively))
3933 tree vtable;
3934 unsigned HOST_WIDE_INT offset;
3935 tree t = NULL_TREE;
3936 if (jfunc->type == IPA_JF_CONST)
3937 t = ipa_find_agg_cst_from_init (ipa_get_jf_constant (jfunc),
3938 ie->indirect_info->offset, true);
3939 if (!t)
3940 t = ipa_find_agg_cst_from_jfunc_items (&jfunc->agg, new_root_info,
3941 new_root,
3942 ie->indirect_info->offset, true);
3943 if (t && vtable_pointer_value_to_vtable (t, &vtable, &offset))
3945 bool can_refer;
3946 t = gimple_get_virt_method_for_vtable (ie->indirect_info->otr_token,
3947 vtable, offset, &can_refer);
3948 if (can_refer)
3950 if (!t
3951 || fndecl_built_in_p (t, BUILT_IN_UNREACHABLE,
3952 BUILT_IN_UNREACHABLE_TRAP)
3953 || !possible_polymorphic_call_target_p
3954 (ie, cgraph_node::get (t)))
3956 /* Do not speculate builtin_unreachable, it is stupid! */
3957 if (!ie->indirect_info->vptr_changed)
3958 target = ipa_impossible_devirt_target (ie, target);
3959 else
3960 target = NULL;
3962 else
3964 target = t;
3965 speculative = ie->indirect_info->vptr_changed;
3971 ipa_polymorphic_call_context ie_context (ie);
3972 vec <cgraph_node *>targets;
3973 bool final;
3975 ctx.offset_by (ie->indirect_info->offset);
3976 if (ie->indirect_info->vptr_changed)
3977 ctx.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
3978 ie->indirect_info->otr_type);
3979 ctx.combine_with (ie_context, ie->indirect_info->otr_type);
3980 targets = possible_polymorphic_call_targets
3981 (ie->indirect_info->otr_type,
3982 ie->indirect_info->otr_token,
3983 ctx, &final);
3984 if (final && targets.length () <= 1)
3986 speculative = false;
3987 if (targets.length () == 1)
3988 target = targets[0]->decl;
3989 else
3990 target = ipa_impossible_devirt_target (ie, NULL_TREE);
3992 else if (!target && opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively)
3993 && !ie->speculative && ie->maybe_hot_p ())
3995 cgraph_node *n;
3996 n = try_speculative_devirtualization (ie->indirect_info->otr_type,
3997 ie->indirect_info->otr_token,
3998 ie->indirect_info->context);
3999 if (n)
4001 target = n->decl;
4002 speculative = true;
4006 if (target)
4008 if (!possible_polymorphic_call_target_p
4009 (ie, cgraph_node::get_create (target)))
4011 if (speculative)
4012 return NULL;
4013 target = ipa_impossible_devirt_target (ie, target);
4015 return ipa_make_edge_direct_to_target (ie, target, speculative);
4017 else
4018 return NULL;
4021 /* Update the param called notes associated with NODE when CS is being inlined,
4022 assuming NODE is (potentially indirectly) inlined into CS->callee.
4023 Moreover, if the callee is discovered to be constant, create a new cgraph
4024 edge for it. Newly discovered indirect edges will be added to *NEW_EDGES,
4025 unless NEW_EDGES is NULL. Return true iff a new edge(s) were created. */
4027 static bool
4028 update_indirect_edges_after_inlining (struct cgraph_edge *cs,
4029 struct cgraph_node *node,
4030 vec<cgraph_edge *> *new_edges)
4032 class ipa_edge_args *top;
4033 struct cgraph_edge *ie, *next_ie, *new_direct_edge;
4034 struct cgraph_node *new_root;
4035 class ipa_node_params *new_root_info, *inlined_node_info;
4036 bool res = false;
4038 ipa_check_create_edge_args ();
4039 top = ipa_edge_args_sum->get (cs);
4040 new_root = cs->caller->inlined_to
4041 ? cs->caller->inlined_to : cs->caller;
4042 new_root_info = ipa_node_params_sum->get (new_root);
4043 inlined_node_info = ipa_node_params_sum->get (cs->callee->function_symbol ());
4045 for (ie = node->indirect_calls; ie; ie = next_ie)
4047 class cgraph_indirect_call_info *ici = ie->indirect_info;
4048 struct ipa_jump_func *jfunc;
4049 int param_index;
4051 next_ie = ie->next_callee;
4053 if (ici->param_index == -1)
4054 continue;
4056 /* We must check range due to calls with variable number of arguments: */
4057 if (!top || ici->param_index >= ipa_get_cs_argument_count (top))
4059 ici->param_index = -1;
4060 continue;
4063 param_index = ici->param_index;
4064 jfunc = ipa_get_ith_jump_func (top, param_index);
4066 auto_vec<cgraph_node *, 4> spec_targets;
4067 if (ie->speculative)
4068 for (cgraph_edge *direct = ie->first_speculative_call_target ();
4069 direct;
4070 direct = direct->next_speculative_call_target ())
4071 spec_targets.safe_push (direct->callee);
4073 if (!opt_for_fn (node->decl, flag_indirect_inlining))
4074 new_direct_edge = NULL;
4075 else if (ici->polymorphic)
4077 ipa_polymorphic_call_context ctx;
4078 ctx = ipa_context_from_jfunc (new_root_info, cs, param_index, jfunc);
4079 new_direct_edge = try_make_edge_direct_virtual_call (ie, jfunc, ctx,
4080 new_root,
4081 new_root_info);
4083 else
4085 tree target_type = ipa_get_type (inlined_node_info, param_index);
4086 new_direct_edge = try_make_edge_direct_simple_call (ie, jfunc,
4087 target_type,
4088 new_root,
4089 new_root_info);
4092 /* If speculation was removed, then we need to do nothing. */
4093 if (new_direct_edge && new_direct_edge != ie
4094 && spec_targets.contains (new_direct_edge->callee))
4096 new_direct_edge->indirect_inlining_edge = 1;
4097 res = true;
4098 if (!new_direct_edge->speculative)
4099 continue;
4101 else if (new_direct_edge)
4103 new_direct_edge->indirect_inlining_edge = 1;
4104 if (new_edges)
4106 new_edges->safe_push (new_direct_edge);
4107 res = true;
4109 /* If speculative edge was introduced we still need to update
4110 call info of the indirect edge. */
4111 if (!new_direct_edge->speculative)
4112 continue;
4114 if (jfunc->type == IPA_JF_PASS_THROUGH
4115 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
4117 if (ici->agg_contents
4118 && !ipa_get_jf_pass_through_agg_preserved (jfunc)
4119 && !ici->polymorphic)
4120 ici->param_index = -1;
4121 else
4123 ici->param_index = ipa_get_jf_pass_through_formal_id (jfunc);
4124 if (ici->polymorphic
4125 && !ipa_get_jf_pass_through_type_preserved (jfunc))
4126 ici->vptr_changed = true;
4127 ipa_set_param_used_by_indirect_call (new_root_info,
4128 ici->param_index, true);
4129 if (ici->polymorphic)
4130 ipa_set_param_used_by_polymorphic_call (new_root_info,
4131 ici->param_index, true);
4134 else if (jfunc->type == IPA_JF_ANCESTOR)
4136 if (ici->agg_contents
4137 && !ipa_get_jf_ancestor_agg_preserved (jfunc)
4138 && !ici->polymorphic)
4139 ici->param_index = -1;
4140 else
4142 ici->param_index = ipa_get_jf_ancestor_formal_id (jfunc);
4143 ici->offset += ipa_get_jf_ancestor_offset (jfunc);
4144 if (ici->polymorphic
4145 && !ipa_get_jf_ancestor_type_preserved (jfunc))
4146 ici->vptr_changed = true;
4147 ipa_set_param_used_by_indirect_call (new_root_info,
4148 ici->param_index, true);
4149 if (ici->polymorphic)
4150 ipa_set_param_used_by_polymorphic_call (new_root_info,
4151 ici->param_index, true);
4154 else
4155 /* Either we can find a destination for this edge now or never. */
4156 ici->param_index = -1;
4159 return res;
4162 /* Recursively traverse subtree of NODE (including node) made of inlined
4163 cgraph_edges when CS has been inlined and invoke
4164 update_indirect_edges_after_inlining on all nodes and
4165 update_jump_functions_after_inlining on all non-inlined edges that lead out
4166 of this subtree. Newly discovered indirect edges will be added to
4167 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were
4168 created. */
4170 static bool
4171 propagate_info_to_inlined_callees (struct cgraph_edge *cs,
4172 struct cgraph_node *node,
4173 vec<cgraph_edge *> *new_edges)
4175 struct cgraph_edge *e;
4176 bool res;
4178 res = update_indirect_edges_after_inlining (cs, node, new_edges);
4180 for (e = node->callees; e; e = e->next_callee)
4181 if (!e->inline_failed)
4182 res |= propagate_info_to_inlined_callees (cs, e->callee, new_edges);
4183 else
4184 update_jump_functions_after_inlining (cs, e);
4185 for (e = node->indirect_calls; e; e = e->next_callee)
4186 update_jump_functions_after_inlining (cs, e);
4188 return res;
4191 /* Combine two controlled uses counts as done during inlining. */
4193 static int
4194 combine_controlled_uses_counters (int c, int d)
4196 if (c == IPA_UNDESCRIBED_USE || d == IPA_UNDESCRIBED_USE)
4197 return IPA_UNDESCRIBED_USE;
4198 else
4199 return c + d - 1;
4202 /* Propagate number of controlled users from CS->caleee to the new root of the
4203 tree of inlined nodes. */
4205 static void
4206 propagate_controlled_uses (struct cgraph_edge *cs)
4208 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
4209 if (!args)
4210 return;
4211 struct cgraph_node *new_root = cs->caller->inlined_to
4212 ? cs->caller->inlined_to : cs->caller;
4213 ipa_node_params *new_root_info = ipa_node_params_sum->get (new_root);
4214 ipa_node_params *old_root_info = ipa_node_params_sum->get (cs->callee);
4215 int count, i;
4217 if (!old_root_info)
4218 return;
4220 count = MIN (ipa_get_cs_argument_count (args),
4221 ipa_get_param_count (old_root_info));
4222 for (i = 0; i < count; i++)
4224 struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
4225 struct ipa_cst_ref_desc *rdesc;
4227 if (jf->type == IPA_JF_PASS_THROUGH
4228 && !ipa_get_jf_pass_through_refdesc_decremented (jf))
4230 int src_idx, c, d;
4231 src_idx = ipa_get_jf_pass_through_formal_id (jf);
4232 c = ipa_get_controlled_uses (new_root_info, src_idx);
4233 d = ipa_get_controlled_uses (old_root_info, i);
4235 gcc_checking_assert (ipa_get_jf_pass_through_operation (jf)
4236 == NOP_EXPR || c == IPA_UNDESCRIBED_USE);
4237 c = combine_controlled_uses_counters (c, d);
4238 ipa_set_controlled_uses (new_root_info, src_idx, c);
4239 bool lderef = true;
4240 if (c != IPA_UNDESCRIBED_USE)
4242 lderef = (ipa_get_param_load_dereferenced (new_root_info, src_idx)
4243 || ipa_get_param_load_dereferenced (old_root_info, i));
4244 ipa_set_param_load_dereferenced (new_root_info, src_idx, lderef);
4247 if (c == 0 && !lderef && new_root_info->ipcp_orig_node)
4249 struct cgraph_node *n;
4250 struct ipa_ref *ref;
4251 tree t = new_root_info->known_csts[src_idx];
4253 if (t && TREE_CODE (t) == ADDR_EXPR
4254 && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
4255 && (n = cgraph_node::get (TREE_OPERAND (t, 0)))
4256 && (ref = new_root->find_reference (n, NULL, 0,
4257 IPA_REF_ADDR)))
4259 if (dump_file)
4260 fprintf (dump_file, "ipa-prop: Removing cloning-created "
4261 "reference from %s to %s.\n",
4262 new_root->dump_name (),
4263 n->dump_name ());
4264 ref->remove_reference ();
4268 else if (jf->type == IPA_JF_CONST
4269 && (rdesc = jfunc_rdesc_usable (jf)))
4271 int d = ipa_get_controlled_uses (old_root_info, i);
4272 int c = rdesc->refcount;
4273 tree cst = ipa_get_jf_constant (jf);
4274 rdesc->refcount = combine_controlled_uses_counters (c, d);
4275 if (rdesc->refcount != IPA_UNDESCRIBED_USE
4276 && ipa_get_param_load_dereferenced (old_root_info, i)
4277 && TREE_CODE (cst) == ADDR_EXPR
4278 && VAR_P (TREE_OPERAND (cst, 0)))
4280 symtab_node *n = symtab_node::get (TREE_OPERAND (cst, 0));
4281 new_root->create_reference (n, IPA_REF_LOAD, NULL);
4282 if (dump_file)
4283 fprintf (dump_file, "ipa-prop: Address IPA constant will reach "
4284 "a load so adding LOAD reference from %s to %s.\n",
4285 new_root->dump_name (), n->dump_name ());
4287 if (rdesc->refcount == 0)
4289 gcc_checking_assert (TREE_CODE (cst) == ADDR_EXPR
4290 && ((TREE_CODE (TREE_OPERAND (cst, 0))
4291 == FUNCTION_DECL)
4292 || VAR_P (TREE_OPERAND (cst, 0))));
4294 symtab_node *n = symtab_node::get (TREE_OPERAND (cst, 0));
4295 if (n)
4297 remove_described_reference (n, rdesc);
4298 cgraph_node *clone = cs->caller;
4299 while (clone->inlined_to
4300 && clone->ipcp_clone
4301 && clone != rdesc->cs->caller)
4303 struct ipa_ref *ref;
4304 ref = clone->find_reference (n, NULL, 0, IPA_REF_ADDR);
4305 if (ref)
4307 if (dump_file)
4308 fprintf (dump_file, "ipa-prop: Removing "
4309 "cloning-created reference "
4310 "from %s to %s.\n",
4311 clone->dump_name (),
4312 n->dump_name ());
4313 ref->remove_reference ();
4315 clone = clone->callers->caller;
4322 for (i = ipa_get_param_count (old_root_info);
4323 i < ipa_get_cs_argument_count (args);
4324 i++)
4326 struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
4328 if (jf->type == IPA_JF_CONST)
4330 struct ipa_cst_ref_desc *rdesc = jfunc_rdesc_usable (jf);
4331 if (rdesc)
4332 rdesc->refcount = IPA_UNDESCRIBED_USE;
4334 else if (jf->type == IPA_JF_PASS_THROUGH)
4335 ipa_set_controlled_uses (new_root_info,
4336 jf->value.pass_through.formal_id,
4337 IPA_UNDESCRIBED_USE);
4341 /* Update jump functions and call note functions on inlining the call site CS.
4342 CS is expected to lead to a node already cloned by
4343 cgraph_clone_inline_nodes. Newly discovered indirect edges will be added to
4344 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were +
4345 created. */
4347 bool
4348 ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
4349 vec<cgraph_edge *> *new_edges)
4351 bool changed;
4352 /* Do nothing if the preparation phase has not been carried out yet
4353 (i.e. during early inlining). */
4354 if (!ipa_node_params_sum)
4355 return false;
4356 gcc_assert (ipa_edge_args_sum);
4358 propagate_controlled_uses (cs);
4359 changed = propagate_info_to_inlined_callees (cs, cs->callee, new_edges);
4360 ipa_node_params_sum->remove (cs->callee);
4362 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
4363 if (args)
4365 bool ok = true;
4366 if (args->jump_functions)
4368 struct ipa_jump_func *jf;
4369 int i;
4370 FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
4371 if (jf->type == IPA_JF_CONST
4372 && ipa_get_jf_constant_rdesc (jf))
4374 ok = false;
4375 break;
4378 if (ok)
4379 ipa_edge_args_sum->remove (cs);
4381 if (ipcp_transformation_sum)
4382 ipcp_transformation_sum->remove (cs->callee);
4384 return changed;
4387 /* Ensure that array of edge arguments infos is big enough to accommodate a
4388 structure for all edges and reallocates it if not. Also, allocate
4389 associated hash tables is they do not already exist. */
4391 void
4392 ipa_check_create_edge_args (void)
4394 if (!ipa_edge_args_sum)
4395 ipa_edge_args_sum
4396 = (new (ggc_alloc_no_dtor<ipa_edge_args_sum_t> ())
4397 ipa_edge_args_sum_t (symtab, true));
4398 if (!ipa_bits_hash_table)
4399 ipa_bits_hash_table = hash_table<ipa_bit_ggc_hash_traits>::create_ggc (37);
4400 if (!ipa_vr_hash_table)
4401 ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
4404 /* Free all ipa_edge structures. */
4406 void
4407 ipa_free_all_edge_args (void)
4409 if (!ipa_edge_args_sum)
4410 return;
4412 ggc_delete (ipa_edge_args_sum);
4413 ipa_edge_args_sum = NULL;
4416 /* Free all ipa_node_params structures. */
4418 void
4419 ipa_free_all_node_params (void)
4421 if (ipa_node_params_sum)
4422 ggc_delete (ipa_node_params_sum);
4423 ipa_node_params_sum = NULL;
4426 /* Initialize IPA CP transformation summary and also allocate any necessary hash
4427 tables if they do not already exist. */
4429 void
4430 ipcp_transformation_initialize (void)
4432 if (!ipa_bits_hash_table)
4433 ipa_bits_hash_table = hash_table<ipa_bit_ggc_hash_traits>::create_ggc (37);
4434 if (!ipa_vr_hash_table)
4435 ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
4436 if (ipcp_transformation_sum == NULL)
4438 ipcp_transformation_sum = ipcp_transformation_t::create_ggc (symtab);
4439 ipcp_transformation_sum->disable_insertion_hook ();
4443 /* Release the IPA CP transformation summary. */
4445 void
4446 ipcp_free_transformation_sum (void)
4448 if (!ipcp_transformation_sum)
4449 return;
4451 ipcp_transformation_sum->~function_summary<ipcp_transformation *> ();
4452 ggc_free (ipcp_transformation_sum);
4453 ipcp_transformation_sum = NULL;
4456 /* Set the aggregate replacements of NODE to be AGGVALS. */
4458 void
4459 ipa_set_node_agg_value_chain (struct cgraph_node *node,
4460 vec<ipa_argagg_value, va_gc> *aggs)
4462 ipcp_transformation_initialize ();
4463 ipcp_transformation *s = ipcp_transformation_sum->get_create (node);
4464 s->m_agg_values = aggs;
4467 /* Hook that is called by cgraph.cc when an edge is removed. Adjust reference
4468 count data structures accordingly. */
4470 void
4471 ipa_edge_args_sum_t::remove (cgraph_edge *cs, ipa_edge_args *args)
4473 if (args->jump_functions)
4475 struct ipa_jump_func *jf;
4476 int i;
4477 FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
4479 struct ipa_cst_ref_desc *rdesc;
4480 try_decrement_rdesc_refcount (jf);
4481 if (jf->type == IPA_JF_CONST
4482 && (rdesc = ipa_get_jf_constant_rdesc (jf))
4483 && rdesc->cs == cs)
4484 rdesc->cs = NULL;
4489 /* Method invoked when an edge is duplicated. Copy ipa_edge_args and adjust
4490 reference count data strucutres accordingly. */
4492 void
4493 ipa_edge_args_sum_t::duplicate (cgraph_edge *src, cgraph_edge *dst,
4494 ipa_edge_args *old_args, ipa_edge_args *new_args)
4496 unsigned int i;
4498 new_args->jump_functions = vec_safe_copy (old_args->jump_functions);
4499 if (old_args->polymorphic_call_contexts)
4500 new_args->polymorphic_call_contexts
4501 = vec_safe_copy (old_args->polymorphic_call_contexts);
4503 for (i = 0; i < vec_safe_length (old_args->jump_functions); i++)
4505 struct ipa_jump_func *src_jf = ipa_get_ith_jump_func (old_args, i);
4506 struct ipa_jump_func *dst_jf = ipa_get_ith_jump_func (new_args, i);
4508 dst_jf->agg.items = vec_safe_copy (dst_jf->agg.items);
4510 if (src_jf->type == IPA_JF_CONST)
4512 struct ipa_cst_ref_desc *src_rdesc = jfunc_rdesc_usable (src_jf);
4514 if (!src_rdesc)
4515 dst_jf->value.constant.rdesc = NULL;
4516 else if (src->caller == dst->caller)
4518 /* Creation of a speculative edge. If the source edge is the one
4519 grabbing a reference, we must create a new (duplicate)
4520 reference description. Otherwise they refer to the same
4521 description corresponding to a reference taken in a function
4522 src->caller is inlined to. In that case we just must
4523 increment the refcount. */
4524 if (src_rdesc->cs == src)
4526 symtab_node *n = symtab_node_for_jfunc (src_jf);
4527 gcc_checking_assert (n);
4528 ipa_ref *ref
4529 = src->caller->find_reference (n, src->call_stmt,
4530 src->lto_stmt_uid,
4531 IPA_REF_ADDR);
4532 gcc_checking_assert (ref);
4533 dst->caller->clone_reference (ref, ref->stmt);
4535 ipa_cst_ref_desc *dst_rdesc = ipa_refdesc_pool.allocate ();
4536 dst_rdesc->cs = dst;
4537 dst_rdesc->refcount = src_rdesc->refcount;
4538 dst_rdesc->next_duplicate = NULL;
4539 dst_jf->value.constant.rdesc = dst_rdesc;
4541 else
4543 src_rdesc->refcount++;
4544 dst_jf->value.constant.rdesc = src_rdesc;
4547 else if (src_rdesc->cs == src)
4549 struct ipa_cst_ref_desc *dst_rdesc = ipa_refdesc_pool.allocate ();
4550 dst_rdesc->cs = dst;
4551 dst_rdesc->refcount = src_rdesc->refcount;
4552 dst_rdesc->next_duplicate = src_rdesc->next_duplicate;
4553 src_rdesc->next_duplicate = dst_rdesc;
4554 dst_jf->value.constant.rdesc = dst_rdesc;
4556 else
4558 struct ipa_cst_ref_desc *dst_rdesc;
4559 /* This can happen during inlining, when a JFUNC can refer to a
4560 reference taken in a function up in the tree of inline clones.
4561 We need to find the duplicate that refers to our tree of
4562 inline clones. */
4564 gcc_assert (dst->caller->inlined_to);
4565 for (dst_rdesc = src_rdesc->next_duplicate;
4566 dst_rdesc;
4567 dst_rdesc = dst_rdesc->next_duplicate)
4569 struct cgraph_node *top;
4570 top = dst_rdesc->cs->caller->inlined_to
4571 ? dst_rdesc->cs->caller->inlined_to
4572 : dst_rdesc->cs->caller;
4573 if (dst->caller->inlined_to == top)
4574 break;
4576 gcc_assert (dst_rdesc);
4577 dst_jf->value.constant.rdesc = dst_rdesc;
4580 else if (dst_jf->type == IPA_JF_PASS_THROUGH
4581 && src->caller == dst->caller)
4583 struct cgraph_node *inline_root = dst->caller->inlined_to
4584 ? dst->caller->inlined_to : dst->caller;
4585 ipa_node_params *root_info = ipa_node_params_sum->get (inline_root);
4586 int idx = ipa_get_jf_pass_through_formal_id (dst_jf);
4588 int c = ipa_get_controlled_uses (root_info, idx);
4589 if (c != IPA_UNDESCRIBED_USE)
4591 c++;
4592 ipa_set_controlled_uses (root_info, idx, c);
4598 /* Analyze newly added function into callgraph. */
4600 static void
4601 ipa_add_new_function (cgraph_node *node, void *data ATTRIBUTE_UNUSED)
4603 if (node->has_gimple_body_p ())
4604 ipa_analyze_node (node);
4607 /* Hook that is called by summary when a node is duplicated. */
4609 void
4610 ipa_node_params_t::duplicate(cgraph_node *, cgraph_node *,
4611 ipa_node_params *old_info,
4612 ipa_node_params *new_info)
4614 new_info->descriptors = vec_safe_copy (old_info->descriptors);
4615 new_info->lattices = NULL;
4616 new_info->ipcp_orig_node = old_info->ipcp_orig_node;
4617 new_info->known_csts = old_info->known_csts.copy ();
4618 new_info->known_contexts = old_info->known_contexts.copy ();
4620 new_info->analysis_done = old_info->analysis_done;
4621 new_info->node_enqueued = old_info->node_enqueued;
4622 new_info->versionable = old_info->versionable;
4625 /* Duplication of ipcp transformation summaries. */
4627 void
4628 ipcp_transformation_t::duplicate(cgraph_node *, cgraph_node *dst,
4629 ipcp_transformation *src_trans,
4630 ipcp_transformation *dst_trans)
4632 /* Avoid redundant work of duplicating vectors we will never use. */
4633 if (dst->inlined_to)
4634 return;
4635 dst_trans->m_agg_values = vec_safe_copy (src_trans->m_agg_values);
4636 dst_trans->bits = vec_safe_copy (src_trans->bits);
4637 dst_trans->m_vr = vec_safe_copy (src_trans->m_vr);
4640 /* Register our cgraph hooks if they are not already there. */
4642 void
4643 ipa_register_cgraph_hooks (void)
4645 ipa_check_create_node_params ();
4646 ipa_check_create_edge_args ();
4648 function_insertion_hook_holder =
4649 symtab->add_cgraph_insertion_hook (&ipa_add_new_function, NULL);
4652 /* Unregister our cgraph hooks if they are not already there. */
4654 static void
4655 ipa_unregister_cgraph_hooks (void)
4657 if (function_insertion_hook_holder)
4658 symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
4659 function_insertion_hook_holder = NULL;
4662 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
4663 longer needed after ipa-cp. */
4665 void
4666 ipa_free_all_structures_after_ipa_cp (void)
4668 if (!optimize && !in_lto_p)
4670 ipa_free_all_edge_args ();
4671 ipa_free_all_node_params ();
4672 ipcp_sources_pool.release ();
4673 ipcp_cst_values_pool.release ();
4674 ipcp_poly_ctx_values_pool.release ();
4675 ipcp_agg_lattice_pool.release ();
4676 ipa_unregister_cgraph_hooks ();
4677 ipa_refdesc_pool.release ();
4681 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
4682 longer needed after indirect inlining. */
4684 void
4685 ipa_free_all_structures_after_iinln (void)
4687 ipa_free_all_edge_args ();
4688 ipa_free_all_node_params ();
4689 ipa_unregister_cgraph_hooks ();
4690 ipcp_sources_pool.release ();
4691 ipcp_cst_values_pool.release ();
4692 ipcp_poly_ctx_values_pool.release ();
4693 ipcp_agg_lattice_pool.release ();
4694 ipa_refdesc_pool.release ();
4697 /* Print ipa_tree_map data structures of all functions in the
4698 callgraph to F. */
4700 void
4701 ipa_print_node_params (FILE *f, struct cgraph_node *node)
4703 int i, count;
4704 class ipa_node_params *info;
4706 if (!node->definition)
4707 return;
4708 info = ipa_node_params_sum->get (node);
4709 fprintf (f, " function %s parameter descriptors:\n", node->dump_name ());
4710 if (!info)
4712 fprintf (f, " no params return\n");
4713 return;
4715 count = ipa_get_param_count (info);
4716 for (i = 0; i < count; i++)
4718 int c;
4720 fprintf (f, " ");
4721 ipa_dump_param (f, info, i);
4722 if (ipa_is_param_used (info, i))
4723 fprintf (f, " used");
4724 if (ipa_is_param_used_by_ipa_predicates (info, i))
4725 fprintf (f, " used_by_ipa_predicates");
4726 if (ipa_is_param_used_by_indirect_call (info, i))
4727 fprintf (f, " used_by_indirect_call");
4728 if (ipa_is_param_used_by_polymorphic_call (info, i))
4729 fprintf (f, " used_by_polymorphic_call");
4730 c = ipa_get_controlled_uses (info, i);
4731 if (c == IPA_UNDESCRIBED_USE)
4732 fprintf (f, " undescribed_use");
4733 else
4734 fprintf (f, " controlled_uses=%i %s", c,
4735 ipa_get_param_load_dereferenced (info, i)
4736 ? "(load_dereferenced)" : "");
4737 fprintf (f, "\n");
4741 /* Print ipa_tree_map data structures of all functions in the
4742 callgraph to F. */
4744 void
4745 ipa_print_all_params (FILE * f)
4747 struct cgraph_node *node;
4749 fprintf (f, "\nFunction parameters:\n");
4750 FOR_EACH_FUNCTION (node)
4751 ipa_print_node_params (f, node);
4754 /* Stream out jump function JUMP_FUNC to OB. */
4756 static void
4757 ipa_write_jump_function (struct output_block *ob,
4758 struct ipa_jump_func *jump_func)
4760 struct ipa_agg_jf_item *item;
4761 struct bitpack_d bp;
4762 int i, count;
4763 int flag = 0;
4765 /* ADDR_EXPRs are very comon IP invariants; save some streamer data
4766 as well as WPA memory by handling them specially. */
4767 if (jump_func->type == IPA_JF_CONST
4768 && TREE_CODE (jump_func->value.constant.value) == ADDR_EXPR)
4769 flag = 1;
4771 streamer_write_uhwi (ob, jump_func->type * 2 + flag);
4772 switch (jump_func->type)
4774 case IPA_JF_UNKNOWN:
4775 break;
4776 case IPA_JF_CONST:
4777 gcc_assert (
4778 EXPR_LOCATION (jump_func->value.constant.value) == UNKNOWN_LOCATION);
4779 stream_write_tree (ob,
4780 flag
4781 ? TREE_OPERAND (jump_func->value.constant.value, 0)
4782 : jump_func->value.constant.value, true);
4783 break;
4784 case IPA_JF_PASS_THROUGH:
4785 streamer_write_uhwi (ob, jump_func->value.pass_through.operation);
4786 if (jump_func->value.pass_through.operation == NOP_EXPR)
4788 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4789 bp = bitpack_create (ob->main_stream);
4790 bp_pack_value (&bp, jump_func->value.pass_through.agg_preserved, 1);
4791 gcc_assert (!jump_func->value.pass_through.refdesc_decremented);
4792 streamer_write_bitpack (&bp);
4794 else if (TREE_CODE_CLASS (jump_func->value.pass_through.operation)
4795 == tcc_unary)
4796 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4797 else
4799 stream_write_tree (ob, jump_func->value.pass_through.operand, true);
4800 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4802 break;
4803 case IPA_JF_ANCESTOR:
4804 streamer_write_uhwi (ob, jump_func->value.ancestor.offset);
4805 streamer_write_uhwi (ob, jump_func->value.ancestor.formal_id);
4806 bp = bitpack_create (ob->main_stream);
4807 bp_pack_value (&bp, jump_func->value.ancestor.agg_preserved, 1);
4808 bp_pack_value (&bp, jump_func->value.ancestor.keep_null, 1);
4809 streamer_write_bitpack (&bp);
4810 break;
4811 default:
4812 fatal_error (UNKNOWN_LOCATION, "invalid jump function in LTO stream");
4815 count = vec_safe_length (jump_func->agg.items);
4816 streamer_write_uhwi (ob, count);
4817 if (count)
4819 bp = bitpack_create (ob->main_stream);
4820 bp_pack_value (&bp, jump_func->agg.by_ref, 1);
4821 streamer_write_bitpack (&bp);
4824 FOR_EACH_VEC_SAFE_ELT (jump_func->agg.items, i, item)
4826 stream_write_tree (ob, item->type, true);
4827 streamer_write_uhwi (ob, item->offset);
4828 streamer_write_uhwi (ob, item->jftype);
4829 switch (item->jftype)
4831 case IPA_JF_UNKNOWN:
4832 break;
4833 case IPA_JF_CONST:
4834 stream_write_tree (ob, item->value.constant, true);
4835 break;
4836 case IPA_JF_PASS_THROUGH:
4837 case IPA_JF_LOAD_AGG:
4838 streamer_write_uhwi (ob, item->value.pass_through.operation);
4839 streamer_write_uhwi (ob, item->value.pass_through.formal_id);
4840 if (TREE_CODE_CLASS (item->value.pass_through.operation)
4841 != tcc_unary)
4842 stream_write_tree (ob, item->value.pass_through.operand, true);
4843 if (item->jftype == IPA_JF_LOAD_AGG)
4845 stream_write_tree (ob, item->value.load_agg.type, true);
4846 streamer_write_uhwi (ob, item->value.load_agg.offset);
4847 bp = bitpack_create (ob->main_stream);
4848 bp_pack_value (&bp, item->value.load_agg.by_ref, 1);
4849 streamer_write_bitpack (&bp);
4851 break;
4852 default:
4853 fatal_error (UNKNOWN_LOCATION,
4854 "invalid jump function in LTO stream");
4858 bp = bitpack_create (ob->main_stream);
4859 bp_pack_value (&bp, !!jump_func->bits, 1);
4860 streamer_write_bitpack (&bp);
4861 if (jump_func->bits)
4863 streamer_write_widest_int (ob, jump_func->bits->value);
4864 streamer_write_widest_int (ob, jump_func->bits->mask);
4866 bp_pack_value (&bp, !!jump_func->m_vr, 1);
4867 streamer_write_bitpack (&bp);
4868 if (jump_func->m_vr)
4870 tree min, max;
4871 value_range_kind kind = get_legacy_range (*jump_func->m_vr, min, max);
4872 streamer_write_enum (ob->main_stream, value_rang_type,
4873 VR_LAST, kind);
4874 stream_write_tree (ob, min, true);
4875 stream_write_tree (ob, max, true);
4879 /* Read in jump function JUMP_FUNC from IB. */
4881 static void
4882 ipa_read_jump_function (class lto_input_block *ib,
4883 struct ipa_jump_func *jump_func,
4884 struct cgraph_edge *cs,
4885 class data_in *data_in,
4886 bool prevails)
4888 enum jump_func_type jftype;
4889 enum tree_code operation;
4890 int i, count;
4891 int val = streamer_read_uhwi (ib);
4892 bool flag = val & 1;
4894 jftype = (enum jump_func_type) (val / 2);
4895 switch (jftype)
4897 case IPA_JF_UNKNOWN:
4898 ipa_set_jf_unknown (jump_func);
4899 break;
4900 case IPA_JF_CONST:
4902 tree t = stream_read_tree (ib, data_in);
4903 if (flag && prevails)
4904 t = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
4905 ipa_set_jf_constant (jump_func, t, cs);
4907 break;
4908 case IPA_JF_PASS_THROUGH:
4909 operation = (enum tree_code) streamer_read_uhwi (ib);
4910 if (operation == NOP_EXPR)
4912 int formal_id = streamer_read_uhwi (ib);
4913 struct bitpack_d bp = streamer_read_bitpack (ib);
4914 bool agg_preserved = bp_unpack_value (&bp, 1);
4915 ipa_set_jf_simple_pass_through (jump_func, formal_id, agg_preserved);
4917 else if (TREE_CODE_CLASS (operation) == tcc_unary)
4919 int formal_id = streamer_read_uhwi (ib);
4920 ipa_set_jf_unary_pass_through (jump_func, formal_id, operation);
4922 else
4924 tree operand = stream_read_tree (ib, data_in);
4925 int formal_id = streamer_read_uhwi (ib);
4926 ipa_set_jf_arith_pass_through (jump_func, formal_id, operand,
4927 operation);
4929 break;
4930 case IPA_JF_ANCESTOR:
4932 HOST_WIDE_INT offset = streamer_read_uhwi (ib);
4933 int formal_id = streamer_read_uhwi (ib);
4934 struct bitpack_d bp = streamer_read_bitpack (ib);
4935 bool agg_preserved = bp_unpack_value (&bp, 1);
4936 bool keep_null = bp_unpack_value (&bp, 1);
4937 ipa_set_ancestor_jf (jump_func, offset, formal_id, agg_preserved,
4938 keep_null);
4939 break;
4941 default:
4942 fatal_error (UNKNOWN_LOCATION, "invalid jump function in LTO stream");
4945 count = streamer_read_uhwi (ib);
4946 if (prevails)
4948 jump_func->agg.items = NULL;
4949 vec_safe_reserve (jump_func->agg.items, count, true);
4951 if (count)
4953 struct bitpack_d bp = streamer_read_bitpack (ib);
4954 jump_func->agg.by_ref = bp_unpack_value (&bp, 1);
4956 for (i = 0; i < count; i++)
4958 struct ipa_agg_jf_item item;
4959 item.type = stream_read_tree (ib, data_in);
4960 item.offset = streamer_read_uhwi (ib);
4961 item.jftype = (enum jump_func_type) streamer_read_uhwi (ib);
4963 switch (item.jftype)
4965 case IPA_JF_UNKNOWN:
4966 break;
4967 case IPA_JF_CONST:
4968 item.value.constant = stream_read_tree (ib, data_in);
4969 break;
4970 case IPA_JF_PASS_THROUGH:
4971 case IPA_JF_LOAD_AGG:
4972 operation = (enum tree_code) streamer_read_uhwi (ib);
4973 item.value.pass_through.operation = operation;
4974 item.value.pass_through.formal_id = streamer_read_uhwi (ib);
4975 if (TREE_CODE_CLASS (operation) == tcc_unary)
4976 item.value.pass_through.operand = NULL_TREE;
4977 else
4978 item.value.pass_through.operand = stream_read_tree (ib, data_in);
4979 if (item.jftype == IPA_JF_LOAD_AGG)
4981 struct bitpack_d bp;
4982 item.value.load_agg.type = stream_read_tree (ib, data_in);
4983 item.value.load_agg.offset = streamer_read_uhwi (ib);
4984 bp = streamer_read_bitpack (ib);
4985 item.value.load_agg.by_ref = bp_unpack_value (&bp, 1);
4987 break;
4988 default:
4989 fatal_error (UNKNOWN_LOCATION,
4990 "invalid jump function in LTO stream");
4992 if (prevails)
4993 jump_func->agg.items->quick_push (item);
4996 struct bitpack_d bp = streamer_read_bitpack (ib);
4997 bool bits_known = bp_unpack_value (&bp, 1);
4998 if (bits_known)
5000 widest_int value = streamer_read_widest_int (ib);
5001 widest_int mask = streamer_read_widest_int (ib);
5002 if (prevails)
5003 ipa_set_jfunc_bits (jump_func, value, mask);
5005 else
5006 jump_func->bits = NULL;
5008 struct bitpack_d vr_bp = streamer_read_bitpack (ib);
5009 bool vr_known = bp_unpack_value (&vr_bp, 1);
5010 if (vr_known)
5012 enum value_range_kind type = streamer_read_enum (ib, value_range_kind,
5013 VR_LAST);
5014 tree min = stream_read_tree (ib, data_in);
5015 tree max = stream_read_tree (ib, data_in);
5016 if (prevails)
5017 ipa_set_jfunc_vr (jump_func, type, min, max);
5019 else
5020 jump_func->m_vr = NULL;
5023 /* Stream out parts of cgraph_indirect_call_info corresponding to CS that are
5024 relevant to indirect inlining to OB. */
5026 static void
5027 ipa_write_indirect_edge_info (struct output_block *ob,
5028 struct cgraph_edge *cs)
5030 class cgraph_indirect_call_info *ii = cs->indirect_info;
5031 struct bitpack_d bp;
5033 streamer_write_hwi (ob, ii->param_index);
5034 bp = bitpack_create (ob->main_stream);
5035 bp_pack_value (&bp, ii->polymorphic, 1);
5036 bp_pack_value (&bp, ii->agg_contents, 1);
5037 bp_pack_value (&bp, ii->member_ptr, 1);
5038 bp_pack_value (&bp, ii->by_ref, 1);
5039 bp_pack_value (&bp, ii->guaranteed_unmodified, 1);
5040 bp_pack_value (&bp, ii->vptr_changed, 1);
5041 streamer_write_bitpack (&bp);
5042 if (ii->agg_contents || ii->polymorphic)
5043 streamer_write_hwi (ob, ii->offset);
5044 else
5045 gcc_assert (ii->offset == 0);
5047 if (ii->polymorphic)
5049 streamer_write_hwi (ob, ii->otr_token);
5050 stream_write_tree (ob, ii->otr_type, true);
5051 ii->context.stream_out (ob);
5055 /* Read in parts of cgraph_indirect_call_info corresponding to CS that are
5056 relevant to indirect inlining from IB. */
5058 static void
5059 ipa_read_indirect_edge_info (class lto_input_block *ib,
5060 class data_in *data_in,
5061 struct cgraph_edge *cs,
5062 class ipa_node_params *info)
5064 class cgraph_indirect_call_info *ii = cs->indirect_info;
5065 struct bitpack_d bp;
5067 ii->param_index = (int) streamer_read_hwi (ib);
5068 bp = streamer_read_bitpack (ib);
5069 ii->polymorphic = bp_unpack_value (&bp, 1);
5070 ii->agg_contents = bp_unpack_value (&bp, 1);
5071 ii->member_ptr = bp_unpack_value (&bp, 1);
5072 ii->by_ref = bp_unpack_value (&bp, 1);
5073 ii->guaranteed_unmodified = bp_unpack_value (&bp, 1);
5074 ii->vptr_changed = bp_unpack_value (&bp, 1);
5075 if (ii->agg_contents || ii->polymorphic)
5076 ii->offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
5077 else
5078 ii->offset = 0;
5079 if (ii->polymorphic)
5081 ii->otr_token = (HOST_WIDE_INT) streamer_read_hwi (ib);
5082 ii->otr_type = stream_read_tree (ib, data_in);
5083 ii->context.stream_in (ib, data_in);
5085 if (info && ii->param_index >= 0)
5087 if (ii->polymorphic)
5088 ipa_set_param_used_by_polymorphic_call (info,
5089 ii->param_index , true);
5090 ipa_set_param_used_by_indirect_call (info,
5091 ii->param_index, true);
5095 /* Stream out NODE info to OB. */
5097 static void
5098 ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
5100 int node_ref;
5101 lto_symtab_encoder_t encoder;
5102 ipa_node_params *info = ipa_node_params_sum->get (node);
5103 int j;
5104 struct cgraph_edge *e;
5105 struct bitpack_d bp;
5107 encoder = ob->decl_state->symtab_node_encoder;
5108 node_ref = lto_symtab_encoder_encode (encoder, node);
5109 streamer_write_uhwi (ob, node_ref);
5111 streamer_write_uhwi (ob, ipa_get_param_count (info));
5112 for (j = 0; j < ipa_get_param_count (info); j++)
5113 streamer_write_uhwi (ob, ipa_get_param_move_cost (info, j));
5114 bp = bitpack_create (ob->main_stream);
5115 gcc_assert (info->analysis_done
5116 || ipa_get_param_count (info) == 0);
5117 gcc_assert (!info->node_enqueued);
5118 gcc_assert (!info->ipcp_orig_node);
5119 for (j = 0; j < ipa_get_param_count (info); j++)
5121 /* TODO: We could just not stream the bit in the undescribed case. */
5122 bool d = (ipa_get_controlled_uses (info, j) != IPA_UNDESCRIBED_USE)
5123 ? ipa_get_param_load_dereferenced (info, j) : true;
5124 bp_pack_value (&bp, d, 1);
5125 bp_pack_value (&bp, ipa_is_param_used (info, j), 1);
5127 streamer_write_bitpack (&bp);
5128 for (j = 0; j < ipa_get_param_count (info); j++)
5130 streamer_write_hwi (ob, ipa_get_controlled_uses (info, j));
5131 stream_write_tree (ob, ipa_get_type (info, j), true);
5133 for (e = node->callees; e; e = e->next_callee)
5135 ipa_edge_args *args = ipa_edge_args_sum->get (e);
5137 if (!args)
5139 streamer_write_uhwi (ob, 0);
5140 continue;
5143 streamer_write_uhwi (ob,
5144 ipa_get_cs_argument_count (args) * 2
5145 + (args->polymorphic_call_contexts != NULL));
5146 for (j = 0; j < ipa_get_cs_argument_count (args); j++)
5148 ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
5149 if (args->polymorphic_call_contexts != NULL)
5150 ipa_get_ith_polymorhic_call_context (args, j)->stream_out (ob);
5153 for (e = node->indirect_calls; e; e = e->next_callee)
5155 ipa_edge_args *args = ipa_edge_args_sum->get (e);
5156 if (!args)
5157 streamer_write_uhwi (ob, 0);
5158 else
5160 streamer_write_uhwi (ob,
5161 ipa_get_cs_argument_count (args) * 2
5162 + (args->polymorphic_call_contexts != NULL));
5163 for (j = 0; j < ipa_get_cs_argument_count (args); j++)
5165 ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
5166 if (args->polymorphic_call_contexts != NULL)
5167 ipa_get_ith_polymorhic_call_context (args, j)->stream_out (ob);
5170 ipa_write_indirect_edge_info (ob, e);
5174 /* Stream in edge E from IB. */
5176 static void
5177 ipa_read_edge_info (class lto_input_block *ib,
5178 class data_in *data_in,
5179 struct cgraph_edge *e, bool prevails)
5181 int count = streamer_read_uhwi (ib);
5182 bool contexts_computed = count & 1;
5184 count /= 2;
5185 if (!count)
5186 return;
5187 if (prevails
5188 && (e->possibly_call_in_translation_unit_p ()
5189 /* Also stream in jump functions to builtins in hope that they
5190 will get fnspecs. */
5191 || fndecl_built_in_p (e->callee->decl, BUILT_IN_NORMAL)))
5193 ipa_edge_args *args = ipa_edge_args_sum->get_create (e);
5194 vec_safe_grow_cleared (args->jump_functions, count, true);
5195 if (contexts_computed)
5196 vec_safe_grow_cleared (args->polymorphic_call_contexts, count, true);
5197 for (int k = 0; k < count; k++)
5199 ipa_read_jump_function (ib, ipa_get_ith_jump_func (args, k), e,
5200 data_in, prevails);
5201 if (contexts_computed)
5202 ipa_get_ith_polymorhic_call_context (args, k)->stream_in
5203 (ib, data_in);
5206 else
5208 for (int k = 0; k < count; k++)
5210 struct ipa_jump_func dummy;
5211 ipa_read_jump_function (ib, &dummy, e,
5212 data_in, prevails);
5213 if (contexts_computed)
5215 class ipa_polymorphic_call_context ctx;
5216 ctx.stream_in (ib, data_in);
5222 /* Stream in NODE info from IB. */
5224 static void
5225 ipa_read_node_info (class lto_input_block *ib, struct cgraph_node *node,
5226 class data_in *data_in)
5228 int k;
5229 struct cgraph_edge *e;
5230 struct bitpack_d bp;
5231 bool prevails = node->prevailing_p ();
5232 ipa_node_params *info
5233 = prevails ? ipa_node_params_sum->get_create (node) : NULL;
5235 int param_count = streamer_read_uhwi (ib);
5236 if (prevails)
5238 ipa_alloc_node_params (node, param_count);
5239 for (k = 0; k < param_count; k++)
5240 (*info->descriptors)[k].move_cost = streamer_read_uhwi (ib);
5241 if (ipa_get_param_count (info) != 0)
5242 info->analysis_done = true;
5243 info->node_enqueued = false;
5245 else
5246 for (k = 0; k < param_count; k++)
5247 streamer_read_uhwi (ib);
5249 bp = streamer_read_bitpack (ib);
5250 for (k = 0; k < param_count; k++)
5252 bool load_dereferenced = bp_unpack_value (&bp, 1);
5253 bool used = bp_unpack_value (&bp, 1);
5255 if (prevails)
5257 ipa_set_param_load_dereferenced (info, k, load_dereferenced);
5258 ipa_set_param_used (info, k, used);
5261 for (k = 0; k < param_count; k++)
5263 int nuses = streamer_read_hwi (ib);
5264 tree type = stream_read_tree (ib, data_in);
5266 if (prevails)
5268 ipa_set_controlled_uses (info, k, nuses);
5269 (*info->descriptors)[k].decl_or_type = type;
5272 for (e = node->callees; e; e = e->next_callee)
5273 ipa_read_edge_info (ib, data_in, e, prevails);
5274 for (e = node->indirect_calls; e; e = e->next_callee)
5276 ipa_read_edge_info (ib, data_in, e, prevails);
5277 ipa_read_indirect_edge_info (ib, data_in, e, info);
5281 /* Write jump functions for nodes in SET. */
5283 void
5284 ipa_prop_write_jump_functions (void)
5286 struct output_block *ob;
5287 unsigned int count = 0;
5288 lto_symtab_encoder_iterator lsei;
5289 lto_symtab_encoder_t encoder;
5291 if (!ipa_node_params_sum || !ipa_edge_args_sum)
5292 return;
5294 ob = create_output_block (LTO_section_jump_functions);
5295 encoder = ob->decl_state->symtab_node_encoder;
5296 ob->symbol = NULL;
5297 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
5298 lsei_next_function_in_partition (&lsei))
5300 cgraph_node *node = lsei_cgraph_node (lsei);
5301 if (node->has_gimple_body_p ()
5302 && ipa_node_params_sum->get (node) != NULL)
5303 count++;
5306 streamer_write_uhwi (ob, count);
5308 /* Process all of the functions. */
5309 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
5310 lsei_next_function_in_partition (&lsei))
5312 cgraph_node *node = lsei_cgraph_node (lsei);
5313 if (node->has_gimple_body_p ()
5314 && ipa_node_params_sum->get (node) != NULL)
5315 ipa_write_node_info (ob, node);
5317 streamer_write_char_stream (ob->main_stream, 0);
5318 produce_asm (ob, NULL);
5319 destroy_output_block (ob);
5322 /* Read section in file FILE_DATA of length LEN with data DATA. */
5324 static void
5325 ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
5326 size_t len)
5328 const struct lto_function_header *header =
5329 (const struct lto_function_header *) data;
5330 const int cfg_offset = sizeof (struct lto_function_header);
5331 const int main_offset = cfg_offset + header->cfg_size;
5332 const int string_offset = main_offset + header->main_size;
5333 class data_in *data_in;
5334 unsigned int i;
5335 unsigned int count;
5337 lto_input_block ib_main ((const char *) data + main_offset,
5338 header->main_size, file_data->mode_table);
5340 data_in =
5341 lto_data_in_create (file_data, (const char *) data + string_offset,
5342 header->string_size, vNULL);
5343 count = streamer_read_uhwi (&ib_main);
5345 for (i = 0; i < count; i++)
5347 unsigned int index;
5348 struct cgraph_node *node;
5349 lto_symtab_encoder_t encoder;
5351 index = streamer_read_uhwi (&ib_main);
5352 encoder = file_data->symtab_node_encoder;
5353 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
5354 index));
5355 gcc_assert (node->definition);
5356 ipa_read_node_info (&ib_main, node, data_in);
5358 lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
5359 len);
5360 lto_data_in_delete (data_in);
5363 /* Read ipcp jump functions. */
5365 void
5366 ipa_prop_read_jump_functions (void)
5368 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
5369 struct lto_file_decl_data *file_data;
5370 unsigned int j = 0;
5372 ipa_check_create_node_params ();
5373 ipa_check_create_edge_args ();
5374 ipa_register_cgraph_hooks ();
5376 while ((file_data = file_data_vec[j++]))
5378 size_t len;
5379 const char *data
5380 = lto_get_summary_section_data (file_data, LTO_section_jump_functions,
5381 &len);
5382 if (data)
5383 ipa_prop_read_section (file_data, data, len);
5387 /* Return true if the IPA-CP transformation summary TS is non-NULL and contains
5388 useful info. */
5389 static bool
5390 useful_ipcp_transformation_info_p (ipcp_transformation *ts)
5392 if (!ts)
5393 return false;
5394 if (!vec_safe_is_empty (ts->m_agg_values)
5395 || !vec_safe_is_empty (ts->bits)
5396 || !vec_safe_is_empty (ts->m_vr))
5397 return true;
5398 return false;
5401 /* Write into OB IPA-CP transfromation summary TS describing NODE. */
5403 void
5404 write_ipcp_transformation_info (output_block *ob, cgraph_node *node,
5405 ipcp_transformation *ts)
5407 lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
5408 int node_ref = lto_symtab_encoder_encode (encoder, node);
5409 streamer_write_uhwi (ob, node_ref);
5411 streamer_write_uhwi (ob, vec_safe_length (ts->m_agg_values));
5412 for (const ipa_argagg_value &av : ts->m_agg_values)
5414 struct bitpack_d bp;
5416 stream_write_tree (ob, av.value, true);
5417 streamer_write_uhwi (ob, av.unit_offset);
5418 streamer_write_uhwi (ob, av.index);
5420 bp = bitpack_create (ob->main_stream);
5421 bp_pack_value (&bp, av.by_ref, 1);
5422 streamer_write_bitpack (&bp);
5425 streamer_write_uhwi (ob, vec_safe_length (ts->m_vr));
5426 for (const ipa_vr &parm_vr : ts->m_vr)
5427 parm_vr.streamer_write (ob);
5429 streamer_write_uhwi (ob, vec_safe_length (ts->bits));
5430 for (const ipa_bits *bits_jfunc : ts->bits)
5432 struct bitpack_d bp = bitpack_create (ob->main_stream);
5433 bp_pack_value (&bp, !!bits_jfunc, 1);
5434 streamer_write_bitpack (&bp);
5435 if (bits_jfunc)
5437 streamer_write_widest_int (ob, bits_jfunc->value);
5438 streamer_write_widest_int (ob, bits_jfunc->mask);
5443 /* Stream in the aggregate value replacement chain for NODE from IB. */
5445 static void
5446 read_ipcp_transformation_info (lto_input_block *ib, cgraph_node *node,
5447 data_in *data_in)
5449 unsigned int count, i;
5450 ipcp_transformation_initialize ();
5451 ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
5453 count = streamer_read_uhwi (ib);
5454 if (count > 0)
5456 vec_safe_grow_cleared (ts->m_agg_values, count, true);
5457 for (i = 0; i <count; i++)
5459 ipa_argagg_value *av = &(*ts->m_agg_values)[i];;
5461 av->value = stream_read_tree (ib, data_in);
5462 av->unit_offset = streamer_read_uhwi (ib);
5463 av->index = streamer_read_uhwi (ib);
5465 bitpack_d bp = streamer_read_bitpack (ib);
5466 av->by_ref = bp_unpack_value (&bp, 1);
5470 count = streamer_read_uhwi (ib);
5471 if (count > 0)
5473 vec_safe_grow_cleared (ts->m_vr, count, true);
5474 for (i = 0; i < count; i++)
5476 ipa_vr *parm_vr;
5477 parm_vr = &(*ts->m_vr)[i];
5478 parm_vr->streamer_read (ib, data_in);
5481 count = streamer_read_uhwi (ib);
5482 if (count > 0)
5484 vec_safe_grow_cleared (ts->bits, count, true);
5485 for (i = 0; i < count; i++)
5487 struct bitpack_d bp = streamer_read_bitpack (ib);
5488 bool known = bp_unpack_value (&bp, 1);
5489 if (known)
5491 const widest_int value = streamer_read_widest_int (ib);
5492 const widest_int mask = streamer_read_widest_int (ib);
5493 ipa_bits *bits
5494 = ipa_get_ipa_bits_for_value (value, mask);
5495 (*ts->bits)[i] = bits;
5501 /* Write all aggregate replacement for nodes in set. */
5503 void
5504 ipcp_write_transformation_summaries (void)
5506 struct output_block *ob;
5507 unsigned int count = 0;
5508 lto_symtab_encoder_t encoder;
5510 ob = create_output_block (LTO_section_ipcp_transform);
5511 encoder = ob->decl_state->symtab_node_encoder;
5512 ob->symbol = NULL;
5514 for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
5516 symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
5517 cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
5518 if (!cnode)
5519 continue;
5520 ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
5521 if (useful_ipcp_transformation_info_p (ts)
5522 && lto_symtab_encoder_encode_body_p (encoder, cnode))
5523 count++;
5526 streamer_write_uhwi (ob, count);
5528 for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
5530 symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
5531 cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
5532 if (!cnode)
5533 continue;
5534 ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
5535 if (useful_ipcp_transformation_info_p (ts)
5536 && lto_symtab_encoder_encode_body_p (encoder, cnode))
5537 write_ipcp_transformation_info (ob, cnode, ts);
5539 streamer_write_char_stream (ob->main_stream, 0);
5540 produce_asm (ob, NULL);
5541 destroy_output_block (ob);
5544 /* Read replacements section in file FILE_DATA of length LEN with data
5545 DATA. */
5547 static void
5548 read_replacements_section (struct lto_file_decl_data *file_data,
5549 const char *data,
5550 size_t len)
5552 const struct lto_function_header *header =
5553 (const struct lto_function_header *) data;
5554 const int cfg_offset = sizeof (struct lto_function_header);
5555 const int main_offset = cfg_offset + header->cfg_size;
5556 const int string_offset = main_offset + header->main_size;
5557 class data_in *data_in;
5558 unsigned int i;
5559 unsigned int count;
5561 lto_input_block ib_main ((const char *) data + main_offset,
5562 header->main_size, file_data->mode_table);
5564 data_in = lto_data_in_create (file_data, (const char *) data + string_offset,
5565 header->string_size, vNULL);
5566 count = streamer_read_uhwi (&ib_main);
5568 for (i = 0; i < count; i++)
5570 unsigned int index;
5571 struct cgraph_node *node;
5572 lto_symtab_encoder_t encoder;
5574 index = streamer_read_uhwi (&ib_main);
5575 encoder = file_data->symtab_node_encoder;
5576 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
5577 index));
5578 read_ipcp_transformation_info (&ib_main, node, data_in);
5580 lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
5581 len);
5582 lto_data_in_delete (data_in);
5585 /* Read IPA-CP aggregate replacements. */
5587 void
5588 ipcp_read_transformation_summaries (void)
5590 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
5591 struct lto_file_decl_data *file_data;
5592 unsigned int j = 0;
5594 while ((file_data = file_data_vec[j++]))
5596 size_t len;
5597 const char *data
5598 = lto_get_summary_section_data (file_data, LTO_section_ipcp_transform,
5599 &len);
5600 if (data)
5601 read_replacements_section (file_data, data, len);
5605 /* Adjust the aggregate replacements in TS to reflect any parameter removals
5606 which might have already taken place. If after adjustments there are no
5607 aggregate replacements left, the m_agg_values will be set to NULL. In other
5608 cases, it may be shrunk. */
5610 static void
5611 adjust_agg_replacement_values (cgraph_node *node, ipcp_transformation *ts)
5613 clone_info *cinfo = clone_info::get (node);
5614 if (!cinfo || !cinfo->param_adjustments)
5615 return;
5617 auto_vec<int, 16> new_indices;
5618 cinfo->param_adjustments->get_updated_indices (&new_indices);
5619 bool removed_item = false;
5620 unsigned dst_index = 0;
5621 unsigned count = ts->m_agg_values->length ();
5622 for (unsigned i = 0; i < count; i++)
5624 ipa_argagg_value *v = &(*ts->m_agg_values)[i];
5625 gcc_checking_assert (v->index >= 0);
5627 int new_idx = -1;
5628 if ((unsigned) v->index < new_indices.length ())
5629 new_idx = new_indices[v->index];
5631 if (new_idx >= 0)
5633 v->index = new_idx;
5634 if (removed_item)
5635 (*ts->m_agg_values)[dst_index] = *v;
5636 dst_index++;
5638 else
5639 removed_item = true;
5642 if (dst_index == 0)
5644 ggc_free (ts->m_agg_values);
5645 ts->m_agg_values = NULL;
5647 else if (removed_item)
5648 ts->m_agg_values->truncate (dst_index);
5650 return;
5653 /* Dominator walker driving the ipcp modification phase. */
5655 class ipcp_modif_dom_walker : public dom_walker
5657 public:
5658 ipcp_modif_dom_walker (struct ipa_func_body_info *fbi,
5659 vec<ipa_param_descriptor, va_gc> *descs,
5660 ipcp_transformation *ts, bool *sc)
5661 : dom_walker (CDI_DOMINATORS), m_fbi (fbi), m_descriptors (descs),
5662 m_ts (ts), m_something_changed (sc) {}
5664 edge before_dom_children (basic_block) final override;
5665 bool cleanup_eh ()
5666 { return gimple_purge_all_dead_eh_edges (m_need_eh_cleanup); }
5668 private:
5669 struct ipa_func_body_info *m_fbi;
5670 vec<ipa_param_descriptor, va_gc> *m_descriptors;
5671 ipcp_transformation *m_ts;
5672 bool *m_something_changed;
5673 auto_bitmap m_need_eh_cleanup;
5676 edge
5677 ipcp_modif_dom_walker::before_dom_children (basic_block bb)
5679 gimple_stmt_iterator gsi;
5680 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
5682 gimple *stmt = gsi_stmt (gsi);
5683 tree rhs, val, t;
5684 HOST_WIDE_INT bit_offset;
5685 poly_int64 size;
5686 int index;
5687 bool by_ref, vce;
5689 if (!gimple_assign_load_p (stmt))
5690 continue;
5691 rhs = gimple_assign_rhs1 (stmt);
5692 if (!is_gimple_reg_type (TREE_TYPE (rhs)))
5693 continue;
5695 vce = false;
5696 t = rhs;
5697 while (handled_component_p (t))
5699 /* V_C_E can do things like convert an array of integers to one
5700 bigger integer and similar things we do not handle below. */
5701 if (TREE_CODE (t) == VIEW_CONVERT_EXPR)
5703 vce = true;
5704 break;
5706 t = TREE_OPERAND (t, 0);
5708 if (vce)
5709 continue;
5711 if (!ipa_load_from_parm_agg (m_fbi, m_descriptors, stmt, rhs, &index,
5712 &bit_offset, &size, &by_ref))
5713 continue;
5714 unsigned unit_offset = bit_offset / BITS_PER_UNIT;
5715 ipa_argagg_value_list avl (m_ts);
5716 tree v = avl.get_value (index, unit_offset, by_ref);
5718 if (!v
5719 || maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (v))), size))
5720 continue;
5722 gcc_checking_assert (is_gimple_ip_invariant (v));
5723 if (!useless_type_conversion_p (TREE_TYPE (rhs), TREE_TYPE (v)))
5725 if (fold_convertible_p (TREE_TYPE (rhs), v))
5726 val = fold_build1 (NOP_EXPR, TREE_TYPE (rhs), v);
5727 else if (TYPE_SIZE (TREE_TYPE (rhs))
5728 == TYPE_SIZE (TREE_TYPE (v)))
5729 val = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (rhs), v);
5730 else
5732 if (dump_file)
5734 fprintf (dump_file, " const ");
5735 print_generic_expr (dump_file, v);
5736 fprintf (dump_file, " can't be converted to type of ");
5737 print_generic_expr (dump_file, rhs);
5738 fprintf (dump_file, "\n");
5740 continue;
5743 else
5744 val = v;
5746 if (dump_file && (dump_flags & TDF_DETAILS))
5748 fprintf (dump_file, "Modifying stmt:\n ");
5749 print_gimple_stmt (dump_file, stmt, 0);
5751 gimple_assign_set_rhs_from_tree (&gsi, val);
5752 update_stmt (stmt);
5754 if (dump_file && (dump_flags & TDF_DETAILS))
5756 fprintf (dump_file, "into:\n ");
5757 print_gimple_stmt (dump_file, stmt, 0);
5758 fprintf (dump_file, "\n");
5761 *m_something_changed = true;
5762 if (maybe_clean_eh_stmt (stmt))
5763 bitmap_set_bit (m_need_eh_cleanup, bb->index);
5765 return NULL;
5768 /* Return true if we have recorded VALUE and MASK about PARM.
5769 Set VALUE and MASk accordingly. */
5771 bool
5772 ipcp_get_parm_bits (tree parm, tree *value, widest_int *mask)
5774 cgraph_node *cnode = cgraph_node::get (current_function_decl);
5775 ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
5776 if (!ts || vec_safe_length (ts->bits) == 0)
5777 return false;
5779 int i = 0;
5780 for (tree p = DECL_ARGUMENTS (current_function_decl);
5781 p != parm; p = DECL_CHAIN (p))
5783 i++;
5784 /* Ignore static chain. */
5785 if (!p)
5786 return false;
5789 clone_info *cinfo = clone_info::get (cnode);
5790 if (cinfo && cinfo->param_adjustments)
5792 i = cinfo->param_adjustments->get_original_index (i);
5793 if (i < 0)
5794 return false;
5797 vec<ipa_bits *, va_gc> &bits = *ts->bits;
5798 if (!bits[i])
5799 return false;
5800 *mask = bits[i]->mask;
5801 *value = wide_int_to_tree (TREE_TYPE (parm), bits[i]->value);
5802 return true;
5806 /* Update bits info of formal parameters as described in
5807 ipcp_transformation. */
5809 static void
5810 ipcp_update_bits (struct cgraph_node *node)
5812 ipcp_transformation *ts = ipcp_get_transformation_summary (node);
5814 if (!ts || vec_safe_length (ts->bits) == 0)
5815 return;
5816 vec<ipa_bits *, va_gc> &bits = *ts->bits;
5817 unsigned count = bits.length ();
5818 if (!count)
5819 return;
5821 auto_vec<int, 16> new_indices;
5822 bool need_remapping = false;
5823 clone_info *cinfo = clone_info::get (node);
5824 if (cinfo && cinfo->param_adjustments)
5826 cinfo->param_adjustments->get_updated_indices (&new_indices);
5827 need_remapping = true;
5829 auto_vec <tree, 16> parm_decls;
5830 push_function_arg_decls (&parm_decls, node->decl);
5832 for (unsigned i = 0; i < count; ++i)
5834 tree parm;
5835 if (need_remapping)
5837 if (i >= new_indices.length ())
5838 continue;
5839 int idx = new_indices[i];
5840 if (idx < 0)
5841 continue;
5842 parm = parm_decls[idx];
5844 else
5845 parm = parm_decls[i];
5846 gcc_checking_assert (parm);
5849 if (!bits[i]
5850 || !(INTEGRAL_TYPE_P (TREE_TYPE (parm))
5851 || POINTER_TYPE_P (TREE_TYPE (parm)))
5852 || !is_gimple_reg (parm))
5853 continue;
5855 tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl), parm);
5856 if (!ddef)
5857 continue;
5859 if (dump_file)
5861 fprintf (dump_file, "Adjusting mask for param %u to ", i);
5862 print_hex (bits[i]->mask, dump_file);
5863 fprintf (dump_file, "\n");
5866 if (INTEGRAL_TYPE_P (TREE_TYPE (ddef)))
5868 unsigned prec = TYPE_PRECISION (TREE_TYPE (ddef));
5869 signop sgn = TYPE_SIGN (TREE_TYPE (ddef));
5871 wide_int nonzero_bits = wide_int::from (bits[i]->mask, prec, UNSIGNED)
5872 | wide_int::from (bits[i]->value, prec, sgn);
5873 set_nonzero_bits (ddef, nonzero_bits);
5875 else
5877 unsigned tem = bits[i]->mask.to_uhwi ();
5878 unsigned HOST_WIDE_INT bitpos = bits[i]->value.to_uhwi ();
5879 unsigned align = tem & -tem;
5880 unsigned misalign = bitpos & (align - 1);
5882 if (align > 1)
5884 if (dump_file)
5885 fprintf (dump_file, "Adjusting align: %u, misalign: %u\n", align, misalign);
5887 unsigned old_align, old_misalign;
5888 struct ptr_info_def *pi = get_ptr_info (ddef);
5889 bool old_known = get_ptr_info_alignment (pi, &old_align, &old_misalign);
5891 if (old_known
5892 && old_align > align)
5894 if (dump_file)
5896 fprintf (dump_file, "But alignment was already %u.\n", old_align);
5897 if ((old_misalign & (align - 1)) != misalign)
5898 fprintf (dump_file, "old_misalign (%u) and misalign (%u) mismatch\n",
5899 old_misalign, misalign);
5901 continue;
5904 if (old_known
5905 && ((misalign & (old_align - 1)) != old_misalign)
5906 && dump_file)
5907 fprintf (dump_file, "old_misalign (%u) and misalign (%u) mismatch\n",
5908 old_misalign, misalign);
5910 set_ptr_info_alignment (pi, align, misalign);
5916 /* Update value range of formal parameters as described in
5917 ipcp_transformation. */
5919 static void
5920 ipcp_update_vr (struct cgraph_node *node)
5922 ipcp_transformation *ts = ipcp_get_transformation_summary (node);
5923 if (!ts || vec_safe_length (ts->m_vr) == 0)
5924 return;
5925 const vec<ipa_vr, va_gc> &vr = *ts->m_vr;
5926 unsigned count = vr.length ();
5927 if (!count)
5928 return;
5930 auto_vec<int, 16> new_indices;
5931 bool need_remapping = false;
5932 clone_info *cinfo = clone_info::get (node);
5933 if (cinfo && cinfo->param_adjustments)
5935 cinfo->param_adjustments->get_updated_indices (&new_indices);
5936 need_remapping = true;
5938 auto_vec <tree, 16> parm_decls;
5939 push_function_arg_decls (&parm_decls, node->decl);
5941 for (unsigned i = 0; i < count; ++i)
5943 tree parm;
5944 int remapped_idx;
5945 if (need_remapping)
5947 if (i >= new_indices.length ())
5948 continue;
5949 remapped_idx = new_indices[i];
5950 if (remapped_idx < 0)
5951 continue;
5953 else
5954 remapped_idx = i;
5956 parm = parm_decls[remapped_idx];
5958 gcc_checking_assert (parm);
5959 tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl), parm);
5961 if (!ddef || !is_gimple_reg (parm))
5962 continue;
5964 if (vr[i].known_p ())
5966 value_range tmp;
5967 vr[i].get_vrange (tmp);
5969 if (!tmp.undefined_p () && !tmp.varying_p ())
5971 if (dump_file)
5973 fprintf (dump_file, "Setting value range of param %u "
5974 "(now %i) ", i, remapped_idx);
5975 tmp.dump (dump_file);
5976 fprintf (dump_file, "]\n");
5978 set_range_info (ddef, tmp);
5984 /* IPCP transformation phase doing propagation of aggregate values. */
5986 unsigned int
5987 ipcp_transform_function (struct cgraph_node *node)
5989 struct ipa_func_body_info fbi;
5990 int param_count;
5992 gcc_checking_assert (cfun);
5993 gcc_checking_assert (current_function_decl);
5995 if (dump_file)
5996 fprintf (dump_file, "Modification phase of node %s\n",
5997 node->dump_name ());
5999 ipcp_update_bits (node);
6000 ipcp_update_vr (node);
6001 ipcp_transformation *ts = ipcp_get_transformation_summary (node);
6002 if (!ts || vec_safe_is_empty (ts->m_agg_values))
6003 return 0;
6004 param_count = count_formal_params (node->decl);
6005 if (param_count == 0)
6006 return 0;
6008 adjust_agg_replacement_values (node, ts);
6009 if (vec_safe_is_empty (ts->m_agg_values))
6011 if (dump_file)
6012 fprintf (dump_file, " All affected aggregate parameters were either "
6013 "removed or converted into scalars, phase done.\n");
6014 return 0;
6016 if (dump_file)
6018 fprintf (dump_file, " Aggregate replacements:");
6019 ipa_argagg_value_list avs (ts);
6020 avs.dump (dump_file);
6023 fbi.node = node;
6024 fbi.info = NULL;
6025 fbi.bb_infos = vNULL;
6026 fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
6027 fbi.param_count = param_count;
6028 fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps);
6030 vec<ipa_param_descriptor, va_gc> *descriptors = NULL;
6031 vec_safe_grow_cleared (descriptors, param_count, true);
6032 ipa_populate_param_decls (node, *descriptors);
6033 bool modified_mem_access = false;
6034 calculate_dominance_info (CDI_DOMINATORS);
6035 ipcp_modif_dom_walker walker (&fbi, descriptors, ts, &modified_mem_access);
6036 walker.walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
6037 free_dominance_info (CDI_DOMINATORS);
6038 bool cfg_changed = walker.cleanup_eh ();
6040 int i;
6041 struct ipa_bb_info *bi;
6042 FOR_EACH_VEC_ELT (fbi.bb_infos, i, bi)
6043 free_ipa_bb_info (bi);
6044 fbi.bb_infos.release ();
6046 ipcp_transformation *s = ipcp_transformation_sum->get (node);
6047 s->m_agg_values = NULL;
6048 s->bits = NULL;
6049 s->m_vr = NULL;
6051 vec_free (descriptors);
6052 if (cfg_changed)
6053 delete_unreachable_blocks_update_callgraph (node, false);
6055 return modified_mem_access ? TODO_update_ssa_only_virtuals : 0;
6059 #include "gt-ipa-prop.h"