tree-optimization/114485 - neg induction with partial vectors
[official-gcc.git] / gcc / ipa-prop.cc
blobe8e4918d5a822d3b5b29bab23166e4f5d2701dfb
1 /* Interprocedural analyses.
2 Copyright (C) 2005-2024 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "backend.h"
24 #include "rtl.h"
25 #include "tree.h"
26 #include "gimple.h"
27 #include "alloc-pool.h"
28 #include "tree-pass.h"
29 #include "ssa.h"
30 #include "tree-streamer.h"
31 #include "cgraph.h"
32 #include "diagnostic.h"
33 #include "fold-const.h"
34 #include "gimple-iterator.h"
35 #include "gimple-fold.h"
36 #include "tree-eh.h"
37 #include "calls.h"
38 #include "stor-layout.h"
39 #include "print-tree.h"
40 #include "gimplify.h"
41 #include "gimplify-me.h"
42 #include "gimple-walk.h"
43 #include "symbol-summary.h"
44 #include "sreal.h"
45 #include "ipa-cp.h"
46 #include "ipa-prop.h"
47 #include "tree-cfg.h"
48 #include "tree-dfa.h"
49 #include "tree-inline.h"
50 #include "ipa-fnsummary.h"
51 #include "gimple-pretty-print.h"
52 #include "ipa-utils.h"
53 #include "dbgcnt.h"
54 #include "domwalk.h"
55 #include "builtins.h"
56 #include "tree-cfgcleanup.h"
57 #include "options.h"
58 #include "symtab-clones.h"
59 #include "attr-fnspec.h"
60 #include "gimple-range.h"
61 #include "value-range-storage.h"
63 /* Function summary where the parameter infos are actually stored. */
64 ipa_node_params_t *ipa_node_params_sum = NULL;
66 function_summary <ipcp_transformation *> *ipcp_transformation_sum = NULL;
68 /* Edge summary for IPA-CP edge information. */
69 ipa_edge_args_sum_t *ipa_edge_args_sum;
71 /* Traits for a hash table for reusing ranges. */
73 struct ipa_vr_ggc_hash_traits : public ggc_cache_remove <ipa_vr *>
75 typedef ipa_vr *value_type;
76 typedef const vrange *compare_type;
77 static hashval_t
78 hash (const ipa_vr *p)
80 // This never get called, except in the verification code, as
81 // ipa_get_value_range() calculates the hash itself. This
82 // function is mostly here for completness' sake.
83 Value_Range vr;
84 p->get_vrange (vr);
85 inchash::hash hstate;
86 add_vrange (vr, hstate);
87 return hstate.end ();
89 static bool
90 equal (const ipa_vr *a, const vrange *b)
92 return a->equal_p (*b);
94 static const bool empty_zero_p = true;
95 static void
96 mark_empty (ipa_vr *&p)
98 p = NULL;
100 static bool
101 is_empty (const ipa_vr *p)
103 return p == NULL;
105 static bool
106 is_deleted (const ipa_vr *p)
108 return p == reinterpret_cast<const ipa_vr *> (1);
110 static void
111 mark_deleted (ipa_vr *&p)
113 p = reinterpret_cast<ipa_vr *> (1);
117 /* Hash table for avoid repeated allocations of equal ranges. */
118 static GTY ((cache)) hash_table<ipa_vr_ggc_hash_traits> *ipa_vr_hash_table;
120 /* Holders of ipa cgraph hooks: */
121 static struct cgraph_node_hook_list *function_insertion_hook_holder;
123 /* Description of a reference to an IPA constant. */
124 struct ipa_cst_ref_desc
126 /* Edge that corresponds to the statement which took the reference. */
127 struct cgraph_edge *cs;
128 /* Linked list of duplicates created when call graph edges are cloned. */
129 struct ipa_cst_ref_desc *next_duplicate;
130 /* Number of references in IPA structures, IPA_UNDESCRIBED_USE if the value
131 if out of control. */
132 int refcount;
135 /* Allocation pool for reference descriptions. */
137 static object_allocator<ipa_cst_ref_desc> ipa_refdesc_pool
138 ("IPA-PROP ref descriptions");
140 ipa_vr::ipa_vr ()
141 : m_storage (NULL),
142 m_type (NULL)
146 ipa_vr::ipa_vr (const vrange &r)
147 : m_storage (ggc_alloc_vrange_storage (r)),
148 m_type (r.type ())
152 bool
153 ipa_vr::equal_p (const vrange &r) const
155 gcc_checking_assert (!r.undefined_p ());
156 return (types_compatible_p (m_type, r.type ()) && m_storage->equal_p (r));
159 void
160 ipa_vr::get_vrange (Value_Range &r) const
162 r.set_type (m_type);
163 m_storage->get_vrange (r, m_type);
166 void
167 ipa_vr::set_unknown ()
169 if (m_storage)
170 ggc_free (m_storage);
172 m_storage = NULL;
175 void
176 ipa_vr::streamer_read (lto_input_block *ib, data_in *data_in)
178 struct bitpack_d bp = streamer_read_bitpack (ib);
179 bool known = bp_unpack_value (&bp, 1);
180 if (known)
182 Value_Range vr;
183 streamer_read_value_range (ib, data_in, vr);
184 if (!m_storage || !m_storage->fits_p (vr))
186 if (m_storage)
187 ggc_free (m_storage);
188 m_storage = ggc_alloc_vrange_storage (vr);
190 m_storage->set_vrange (vr);
191 m_type = vr.type ();
193 else
195 m_storage = NULL;
196 m_type = NULL;
200 void
201 ipa_vr::streamer_write (output_block *ob) const
203 struct bitpack_d bp = bitpack_create (ob->main_stream);
204 bp_pack_value (&bp, !!m_storage, 1);
205 streamer_write_bitpack (&bp);
206 if (m_storage)
208 Value_Range vr (m_type);
209 m_storage->get_vrange (vr, m_type);
210 streamer_write_vrange (ob, vr);
214 void
215 ipa_vr::dump (FILE *out) const
217 if (known_p ())
219 Value_Range vr (m_type);
220 m_storage->get_vrange (vr, m_type);
221 vr.dump (out);
223 else
224 fprintf (out, "NO RANGE");
227 // These stubs are because we use an ipa_vr in a hash_traits and
228 // hash-traits.h defines an extern of gt_ggc_mx (T &) instead of
229 // picking up the gt_ggc_mx (T *) version.
230 void
231 gt_pch_nx (ipa_vr *&x)
233 return gt_pch_nx ((ipa_vr *) x);
236 void
237 gt_ggc_mx (ipa_vr *&x)
239 return gt_ggc_mx ((ipa_vr *) x);
242 /* Analysis summery of function call return value. */
243 struct GTY(()) ipa_return_value_summary
245 /* Known value range.
246 This needs to be wrapped in struccture due to specific way
247 we allocate ipa_vr. */
248 ipa_vr *vr;
251 /* Function summary for return values. */
252 class ipa_return_value_sum_t : public function_summary <ipa_return_value_summary *>
254 public:
255 ipa_return_value_sum_t (symbol_table *table, bool ggc):
256 function_summary <ipa_return_value_summary *> (table, ggc) { }
258 /* Hook that is called by summary when a node is duplicated. */
259 void duplicate (cgraph_node *,
260 cgraph_node *,
261 ipa_return_value_summary *data,
262 ipa_return_value_summary *data2) final override
264 *data2=*data;
268 /* Variable hoding the return value summary. */
269 static GTY(()) function_summary <ipa_return_value_summary *> *ipa_return_value_sum;
272 /* Return true if DECL_FUNCTION_SPECIFIC_OPTIMIZATION of the decl associated
273 with NODE should prevent us from analyzing it for the purposes of IPA-CP. */
275 static bool
276 ipa_func_spec_opts_forbid_analysis_p (struct cgraph_node *node)
278 tree fs_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (node->decl);
280 if (!fs_opts)
281 return false;
282 return !opt_for_fn (node->decl, optimize) || !opt_for_fn (node->decl, flag_ipa_cp);
285 /* Return index of the formal whose tree is PTREE in function which corresponds
286 to INFO. */
288 static int
289 ipa_get_param_decl_index_1 (vec<ipa_param_descriptor, va_gc> *descriptors,
290 tree ptree)
292 int i, count;
294 count = vec_safe_length (descriptors);
295 for (i = 0; i < count; i++)
296 if ((*descriptors)[i].decl_or_type == ptree)
297 return i;
299 return -1;
302 /* Return index of the formal whose tree is PTREE in function which corresponds
303 to INFO. */
306 ipa_get_param_decl_index (class ipa_node_params *info, tree ptree)
308 return ipa_get_param_decl_index_1 (info->descriptors, ptree);
311 /* Populate the param_decl field in parameter DESCRIPTORS that correspond to
312 NODE. */
314 static void
315 ipa_populate_param_decls (struct cgraph_node *node,
316 vec<ipa_param_descriptor, va_gc> &descriptors)
318 tree fndecl;
319 tree fnargs;
320 tree parm;
321 int param_num;
323 fndecl = node->decl;
324 gcc_assert (gimple_has_body_p (fndecl));
325 fnargs = DECL_ARGUMENTS (fndecl);
326 param_num = 0;
327 for (parm = fnargs; parm; parm = DECL_CHAIN (parm))
329 descriptors[param_num].decl_or_type = parm;
330 unsigned int cost = estimate_move_cost (TREE_TYPE (parm), true);
331 descriptors[param_num].move_cost = cost;
332 /* Watch overflow, move_cost is a bitfield. */
333 gcc_checking_assert (cost == descriptors[param_num].move_cost);
334 param_num++;
338 /* Return how many formal parameters FNDECL has. */
341 count_formal_params (tree fndecl)
343 tree parm;
344 int count = 0;
345 gcc_assert (gimple_has_body_p (fndecl));
347 for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
348 count++;
350 return count;
353 /* Return the declaration of Ith formal parameter of the function corresponding
354 to INFO. Note there is no setter function as this array is built just once
355 using ipa_initialize_node_params. */
357 void
358 ipa_dump_param (FILE *file, class ipa_node_params *info, int i)
360 fprintf (file, "param #%i", i);
361 if ((*info->descriptors)[i].decl_or_type)
363 fprintf (file, " ");
364 print_generic_expr (file, (*info->descriptors)[i].decl_or_type);
368 /* If necessary, allocate vector of parameter descriptors in info of NODE.
369 Return true if they were allocated, false if not. */
371 static bool
372 ipa_alloc_node_params (struct cgraph_node *node, int param_count)
374 ipa_node_params *info = ipa_node_params_sum->get_create (node);
376 if (!info->descriptors && param_count)
378 vec_safe_grow_cleared (info->descriptors, param_count, true);
379 return true;
381 else
382 return false;
385 /* Initialize the ipa_node_params structure associated with NODE by counting
386 the function parameters, creating the descriptors and populating their
387 param_decls. */
389 void
390 ipa_initialize_node_params (struct cgraph_node *node)
392 ipa_node_params *info = ipa_node_params_sum->get_create (node);
394 if (!info->descriptors
395 && ipa_alloc_node_params (node, count_formal_params (node->decl)))
396 ipa_populate_param_decls (node, *info->descriptors);
399 /* Print VAL which is extracted from a jump function to F. */
401 static void
402 ipa_print_constant_value (FILE *f, tree val)
404 print_generic_expr (f, val);
406 /* This is in keeping with values_equal_for_ipcp_p. */
407 if (TREE_CODE (val) == ADDR_EXPR
408 && (TREE_CODE (TREE_OPERAND (val, 0)) == CONST_DECL
409 || (TREE_CODE (TREE_OPERAND (val, 0)) == VAR_DECL
410 && DECL_IN_CONSTANT_POOL (TREE_OPERAND (val, 0)))))
412 fputs (" -> ", f);
413 print_generic_expr (f, DECL_INITIAL (TREE_OPERAND (val, 0)));
417 /* Print the jump functions associated with call graph edge CS to file F. */
419 static void
420 ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
422 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
423 int count = ipa_get_cs_argument_count (args);
425 for (int i = 0; i < count; i++)
427 struct ipa_jump_func *jump_func;
428 enum jump_func_type type;
430 jump_func = ipa_get_ith_jump_func (args, i);
431 type = jump_func->type;
433 fprintf (f, " param %d: ", i);
434 if (type == IPA_JF_UNKNOWN)
435 fprintf (f, "UNKNOWN\n");
436 else if (type == IPA_JF_CONST)
438 fprintf (f, "CONST: ");
439 ipa_print_constant_value (f, jump_func->value.constant.value);
440 fprintf (f, "\n");
442 else if (type == IPA_JF_PASS_THROUGH)
444 fprintf (f, "PASS THROUGH: ");
445 fprintf (f, "%d, op %s",
446 jump_func->value.pass_through.formal_id,
447 get_tree_code_name(jump_func->value.pass_through.operation));
448 if (jump_func->value.pass_through.operation != NOP_EXPR)
450 fprintf (f, " ");
451 print_generic_expr (f, jump_func->value.pass_through.operand);
453 if (jump_func->value.pass_through.agg_preserved)
454 fprintf (f, ", agg_preserved");
455 if (jump_func->value.pass_through.refdesc_decremented)
456 fprintf (f, ", refdesc_decremented");
457 fprintf (f, "\n");
459 else if (type == IPA_JF_ANCESTOR)
461 fprintf (f, "ANCESTOR: ");
462 fprintf (f, "%d, offset " HOST_WIDE_INT_PRINT_DEC,
463 jump_func->value.ancestor.formal_id,
464 jump_func->value.ancestor.offset);
465 if (jump_func->value.ancestor.agg_preserved)
466 fprintf (f, ", agg_preserved");
467 if (jump_func->value.ancestor.keep_null)
468 fprintf (f, ", keep_null");
469 fprintf (f, "\n");
472 if (jump_func->agg.items)
474 struct ipa_agg_jf_item *item;
475 int j;
477 fprintf (f, " Aggregate passed by %s:\n",
478 jump_func->agg.by_ref ? "reference" : "value");
479 FOR_EACH_VEC_ELT (*jump_func->agg.items, j, item)
481 fprintf (f, " offset: " HOST_WIDE_INT_PRINT_DEC ", ",
482 item->offset);
483 fprintf (f, "type: ");
484 print_generic_expr (f, item->type);
485 fprintf (f, ", ");
486 if (item->jftype == IPA_JF_PASS_THROUGH)
487 fprintf (f, "PASS THROUGH: %d,",
488 item->value.pass_through.formal_id);
489 else if (item->jftype == IPA_JF_LOAD_AGG)
491 fprintf (f, "LOAD AGG: %d",
492 item->value.pass_through.formal_id);
493 fprintf (f, " [offset: " HOST_WIDE_INT_PRINT_DEC ", by %s],",
494 item->value.load_agg.offset,
495 item->value.load_agg.by_ref ? "reference"
496 : "value");
499 if (item->jftype == IPA_JF_PASS_THROUGH
500 || item->jftype == IPA_JF_LOAD_AGG)
502 fprintf (f, " op %s",
503 get_tree_code_name (item->value.pass_through.operation));
504 if (item->value.pass_through.operation != NOP_EXPR)
506 fprintf (f, " ");
507 print_generic_expr (f, item->value.pass_through.operand);
510 else if (item->jftype == IPA_JF_CONST)
512 fprintf (f, "CONST: ");
513 ipa_print_constant_value (f, item->value.constant);
515 else if (item->jftype == IPA_JF_UNKNOWN)
516 fprintf (f, "UNKNOWN: " HOST_WIDE_INT_PRINT_DEC " bits",
517 tree_to_uhwi (TYPE_SIZE (item->type)));
518 fprintf (f, "\n");
522 class ipa_polymorphic_call_context *ctx
523 = ipa_get_ith_polymorhic_call_context (args, i);
524 if (ctx && !ctx->useless_p ())
526 fprintf (f, " Context: ");
527 ctx->dump (dump_file);
530 if (jump_func->m_vr)
532 jump_func->m_vr->dump (f);
533 fprintf (f, "\n");
535 else
536 fprintf (f, " Unknown VR\n");
541 /* Print the jump functions of all arguments on all call graph edges going from
542 NODE to file F. */
544 void
545 ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
547 struct cgraph_edge *cs;
549 fprintf (f, " Jump functions of caller %s:\n", node->dump_name ());
550 for (cs = node->callees; cs; cs = cs->next_callee)
553 fprintf (f, " callsite %s -> %s : \n",
554 node->dump_name (),
555 cs->callee->dump_name ());
556 if (!ipa_edge_args_info_available_for_edge_p (cs))
557 fprintf (f, " no arg info\n");
558 else
559 ipa_print_node_jump_functions_for_edge (f, cs);
562 for (cs = node->indirect_calls; cs; cs = cs->next_callee)
564 class cgraph_indirect_call_info *ii;
566 ii = cs->indirect_info;
567 if (ii->agg_contents)
568 fprintf (f, " indirect %s callsite, calling param %i, "
569 "offset " HOST_WIDE_INT_PRINT_DEC ", %s",
570 ii->member_ptr ? "member ptr" : "aggregate",
571 ii->param_index, ii->offset,
572 ii->by_ref ? "by reference" : "by_value");
573 else
574 fprintf (f, " indirect %s callsite, calling param %i, "
575 "offset " HOST_WIDE_INT_PRINT_DEC,
576 ii->polymorphic ? "polymorphic" : "simple", ii->param_index,
577 ii->offset);
579 if (cs->call_stmt)
581 fprintf (f, ", for stmt ");
582 print_gimple_stmt (f, cs->call_stmt, 0, TDF_SLIM);
584 else
585 fprintf (f, "\n");
586 if (ii->polymorphic)
587 ii->context.dump (f);
588 if (!ipa_edge_args_info_available_for_edge_p (cs))
589 fprintf (f, " no arg info\n");
590 else
591 ipa_print_node_jump_functions_for_edge (f, cs);
595 /* Print ipa_jump_func data structures of all nodes in the call graph to F. */
597 void
598 ipa_print_all_jump_functions (FILE *f)
600 struct cgraph_node *node;
602 fprintf (f, "\nJump functions:\n");
603 FOR_EACH_FUNCTION (node)
605 ipa_print_node_jump_functions (f, node);
609 /* Set jfunc to be a know-really nothing jump function. */
611 static void
612 ipa_set_jf_unknown (struct ipa_jump_func *jfunc)
614 jfunc->type = IPA_JF_UNKNOWN;
617 /* Set JFUNC to be a copy of another jmp (to be used by jump function
618 combination code). The two functions will share their rdesc. */
620 static void
621 ipa_set_jf_cst_copy (struct ipa_jump_func *dst,
622 struct ipa_jump_func *src)
625 gcc_checking_assert (src->type == IPA_JF_CONST);
626 dst->type = IPA_JF_CONST;
627 dst->value.constant = src->value.constant;
630 /* Set JFUNC to be a constant jmp function. */
632 static void
633 ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
634 struct cgraph_edge *cs)
636 jfunc->type = IPA_JF_CONST;
637 jfunc->value.constant.value = unshare_expr_without_location (constant);
639 if (TREE_CODE (constant) == ADDR_EXPR
640 && (TREE_CODE (TREE_OPERAND (constant, 0)) == FUNCTION_DECL
641 || (VAR_P (TREE_OPERAND (constant, 0))
642 && TREE_STATIC (TREE_OPERAND (constant, 0)))))
644 struct ipa_cst_ref_desc *rdesc;
646 rdesc = ipa_refdesc_pool.allocate ();
647 rdesc->cs = cs;
648 rdesc->next_duplicate = NULL;
649 rdesc->refcount = 1;
650 jfunc->value.constant.rdesc = rdesc;
652 else
653 jfunc->value.constant.rdesc = NULL;
656 /* Set JFUNC to be a simple pass-through jump function. */
657 static void
658 ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
659 bool agg_preserved)
661 jfunc->type = IPA_JF_PASS_THROUGH;
662 jfunc->value.pass_through.operand = NULL_TREE;
663 jfunc->value.pass_through.formal_id = formal_id;
664 jfunc->value.pass_through.operation = NOP_EXPR;
665 jfunc->value.pass_through.agg_preserved = agg_preserved;
666 jfunc->value.pass_through.refdesc_decremented = false;
669 /* Set JFUNC to be an unary pass through jump function. */
671 static void
672 ipa_set_jf_unary_pass_through (struct ipa_jump_func *jfunc, int formal_id,
673 enum tree_code operation)
675 jfunc->type = IPA_JF_PASS_THROUGH;
676 jfunc->value.pass_through.operand = NULL_TREE;
677 jfunc->value.pass_through.formal_id = formal_id;
678 jfunc->value.pass_through.operation = operation;
679 jfunc->value.pass_through.agg_preserved = false;
680 jfunc->value.pass_through.refdesc_decremented = false;
682 /* Set JFUNC to be an arithmetic pass through jump function. */
684 static void
685 ipa_set_jf_arith_pass_through (struct ipa_jump_func *jfunc, int formal_id,
686 tree operand, enum tree_code operation)
688 jfunc->type = IPA_JF_PASS_THROUGH;
689 jfunc->value.pass_through.operand = unshare_expr_without_location (operand);
690 jfunc->value.pass_through.formal_id = formal_id;
691 jfunc->value.pass_through.operation = operation;
692 jfunc->value.pass_through.agg_preserved = false;
693 jfunc->value.pass_through.refdesc_decremented = false;
696 /* Set JFUNC to be an ancestor jump function. */
698 static void
699 ipa_set_ancestor_jf (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
700 int formal_id, bool agg_preserved, bool keep_null)
702 jfunc->type = IPA_JF_ANCESTOR;
703 jfunc->value.ancestor.formal_id = formal_id;
704 jfunc->value.ancestor.offset = offset;
705 jfunc->value.ancestor.agg_preserved = agg_preserved;
706 jfunc->value.ancestor.keep_null = keep_null;
709 /* Get IPA BB information about the given BB. FBI is the context of analyzis
710 of this function body. */
712 static struct ipa_bb_info *
713 ipa_get_bb_info (struct ipa_func_body_info *fbi, basic_block bb)
715 gcc_checking_assert (fbi);
716 return &fbi->bb_infos[bb->index];
719 /* Structure to be passed in between detect_type_change and
720 check_stmt_for_type_change. */
722 struct prop_type_change_info
724 /* Offset into the object where there is the virtual method pointer we are
725 looking for. */
726 HOST_WIDE_INT offset;
727 /* The declaration or SSA_NAME pointer of the base that we are checking for
728 type change. */
729 tree object;
730 /* Set to true if dynamic type change has been detected. */
731 bool type_maybe_changed;
734 /* Return true if STMT can modify a virtual method table pointer.
736 This function makes special assumptions about both constructors and
737 destructors which are all the functions that are allowed to alter the VMT
738 pointers. It assumes that destructors begin with assignment into all VMT
739 pointers and that constructors essentially look in the following way:
741 1) The very first thing they do is that they call constructors of ancestor
742 sub-objects that have them.
744 2) Then VMT pointers of this and all its ancestors is set to new values
745 corresponding to the type corresponding to the constructor.
747 3) Only afterwards, other stuff such as constructor of member sub-objects
748 and the code written by the user is run. Only this may include calling
749 virtual functions, directly or indirectly.
751 There is no way to call a constructor of an ancestor sub-object in any
752 other way.
754 This means that we do not have to care whether constructors get the correct
755 type information because they will always change it (in fact, if we define
756 the type to be given by the VMT pointer, it is undefined).
758 The most important fact to derive from the above is that if, for some
759 statement in the section 3, we try to detect whether the dynamic type has
760 changed, we can safely ignore all calls as we examine the function body
761 backwards until we reach statements in section 2 because these calls cannot
762 be ancestor constructors or destructors (if the input is not bogus) and so
763 do not change the dynamic type (this holds true only for automatically
764 allocated objects but at the moment we devirtualize only these). We then
765 must detect that statements in section 2 change the dynamic type and can try
766 to derive the new type. That is enough and we can stop, we will never see
767 the calls into constructors of sub-objects in this code. Therefore we can
768 safely ignore all call statements that we traverse.
771 static bool
772 stmt_may_be_vtbl_ptr_store (gimple *stmt)
774 if (is_gimple_call (stmt))
775 return false;
776 if (gimple_clobber_p (stmt))
777 return false;
778 else if (is_gimple_assign (stmt))
780 tree lhs = gimple_assign_lhs (stmt);
782 if (!AGGREGATE_TYPE_P (TREE_TYPE (lhs)))
784 if (flag_strict_aliasing
785 && !POINTER_TYPE_P (TREE_TYPE (lhs)))
786 return false;
788 if (TREE_CODE (lhs) == COMPONENT_REF
789 && !DECL_VIRTUAL_P (TREE_OPERAND (lhs, 1)))
790 return false;
791 /* In the future we might want to use get_ref_base_and_extent to find
792 if there is a field corresponding to the offset and if so, proceed
793 almost like if it was a component ref. */
796 return true;
799 /* Callback of walk_aliased_vdefs and a helper function for detect_type_change
800 to check whether a particular statement may modify the virtual table
801 pointerIt stores its result into DATA, which points to a
802 prop_type_change_info structure. */
804 static bool
805 check_stmt_for_type_change (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
807 gimple *stmt = SSA_NAME_DEF_STMT (vdef);
808 struct prop_type_change_info *tci = (struct prop_type_change_info *) data;
810 if (stmt_may_be_vtbl_ptr_store (stmt))
812 tci->type_maybe_changed = true;
813 return true;
815 else
816 return false;
819 /* See if ARG is PARAM_DECl describing instance passed by pointer
820 or reference in FUNCTION. Return false if the dynamic type may change
821 in between beggining of the function until CALL is invoked.
823 Generally functions are not allowed to change type of such instances,
824 but they call destructors. We assume that methods cannot destroy the THIS
825 pointer. Also as a special cases, constructor and destructors may change
826 type of the THIS pointer. */
828 static bool
829 param_type_may_change_p (tree function, tree arg, gimple *call)
831 /* Pure functions cannot do any changes on the dynamic type;
832 that require writting to memory. */
833 if (flags_from_decl_or_type (function) & (ECF_PURE | ECF_CONST))
834 return false;
835 /* We need to check if we are within inlined consturctor
836 or destructor (ideally we would have way to check that the
837 inline cdtor is actually working on ARG, but we don't have
838 easy tie on this, so punt on all non-pure cdtors.
839 We may also record the types of cdtors and once we know type
840 of the instance match them.
842 Also code unification optimizations may merge calls from
843 different blocks making return values unreliable. So
844 do nothing during late optimization. */
845 if (DECL_STRUCT_FUNCTION (function)->after_inlining)
846 return true;
847 if (TREE_CODE (arg) == SSA_NAME
848 && SSA_NAME_IS_DEFAULT_DEF (arg)
849 && TREE_CODE (SSA_NAME_VAR (arg)) == PARM_DECL)
851 /* Normal (non-THIS) argument. */
852 if ((SSA_NAME_VAR (arg) != DECL_ARGUMENTS (function)
853 || TREE_CODE (TREE_TYPE (function)) != METHOD_TYPE)
854 /* THIS pointer of an method - here we want to watch constructors
855 and destructors as those definitely may change the dynamic
856 type. */
857 || (TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE
858 && !DECL_CXX_CONSTRUCTOR_P (function)
859 && !DECL_CXX_DESTRUCTOR_P (function)
860 && (SSA_NAME_VAR (arg) == DECL_ARGUMENTS (function))))
862 /* Walk the inline stack and watch out for ctors/dtors. */
863 for (tree block = gimple_block (call); block && TREE_CODE (block) == BLOCK;
864 block = BLOCK_SUPERCONTEXT (block))
865 if (inlined_polymorphic_ctor_dtor_block_p (block, false))
866 return true;
867 return false;
870 return true;
873 /* Detect whether the dynamic type of ARG of COMP_TYPE has changed (before
874 callsite CALL) by looking for assignments to its virtual table pointer. If
875 it is, return true. ARG is the object itself (not a pointer
876 to it, unless dereferenced). BASE is the base of the memory access as
877 returned by get_ref_base_and_extent, as is the offset.
879 This is helper function for detect_type_change and detect_type_change_ssa
880 that does the heavy work which is usually unnecesary. */
882 static bool
883 detect_type_change_from_memory_writes (ipa_func_body_info *fbi, tree arg,
884 tree base, tree comp_type, gcall *call,
885 HOST_WIDE_INT offset)
887 struct prop_type_change_info tci;
888 ao_ref ao;
890 gcc_checking_assert (DECL_P (arg)
891 || TREE_CODE (arg) == MEM_REF
892 || handled_component_p (arg));
894 comp_type = TYPE_MAIN_VARIANT (comp_type);
896 /* Const calls cannot call virtual methods through VMT and so type changes do
897 not matter. */
898 if (!flag_devirtualize || !gimple_vuse (call)
899 /* Be sure expected_type is polymorphic. */
900 || !comp_type
901 || TREE_CODE (comp_type) != RECORD_TYPE
902 || !TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type))
903 || !BINFO_VTABLE (TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type))))
904 return true;
906 if (fbi->aa_walk_budget == 0)
907 return false;
909 ao_ref_init (&ao, arg);
910 ao.base = base;
911 ao.offset = offset;
912 ao.size = POINTER_SIZE;
913 ao.max_size = ao.size;
915 tci.offset = offset;
916 tci.object = get_base_address (arg);
917 tci.type_maybe_changed = false;
919 int walked
920 = walk_aliased_vdefs (&ao, gimple_vuse (call), check_stmt_for_type_change,
921 &tci, NULL, NULL, fbi->aa_walk_budget);
922 if (walked >= 0)
923 fbi->aa_walk_budget -= walked;
924 else
925 fbi->aa_walk_budget = 0;
927 if (walked >= 0 && !tci.type_maybe_changed)
928 return false;
930 return true;
933 /* Detect whether the dynamic type of ARG of COMP_TYPE may have changed.
934 If it is, return true. ARG is the object itself (not a pointer
935 to it, unless dereferenced). BASE is the base of the memory access as
936 returned by get_ref_base_and_extent, as is the offset. */
938 static bool
939 detect_type_change (ipa_func_body_info *fbi, tree arg, tree base,
940 tree comp_type, gcall *call,
941 HOST_WIDE_INT offset)
943 if (!flag_devirtualize)
944 return false;
946 if (TREE_CODE (base) == MEM_REF
947 && !param_type_may_change_p (current_function_decl,
948 TREE_OPERAND (base, 0),
949 call))
950 return false;
951 return detect_type_change_from_memory_writes (fbi, arg, base, comp_type,
952 call, offset);
955 /* Like detect_type_change but ARG is supposed to be a non-dereferenced pointer
956 SSA name (its dereference will become the base and the offset is assumed to
957 be zero). */
959 static bool
960 detect_type_change_ssa (ipa_func_body_info *fbi, tree arg, tree comp_type,
961 gcall *call)
963 gcc_checking_assert (TREE_CODE (arg) == SSA_NAME);
964 if (!flag_devirtualize
965 || !POINTER_TYPE_P (TREE_TYPE (arg)))
966 return false;
968 if (!param_type_may_change_p (current_function_decl, arg, call))
969 return false;
971 arg = build2 (MEM_REF, ptr_type_node, arg,
972 build_int_cst (ptr_type_node, 0));
974 return detect_type_change_from_memory_writes (fbi, arg, arg, comp_type,
975 call, 0);
978 /* Callback of walk_aliased_vdefs. Flags that it has been invoked to the
979 boolean variable pointed to by DATA. */
981 static bool
982 mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
983 void *data)
985 bool *b = (bool *) data;
986 *b = true;
987 return true;
990 /* Find the nearest valid aa status for parameter specified by INDEX that
991 dominates BB. */
993 static struct ipa_param_aa_status *
994 find_dominating_aa_status (struct ipa_func_body_info *fbi, basic_block bb,
995 int index)
997 while (true)
999 bb = get_immediate_dominator (CDI_DOMINATORS, bb);
1000 if (!bb)
1001 return NULL;
1002 struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
1003 if (!bi->param_aa_statuses.is_empty ()
1004 && bi->param_aa_statuses[index].valid)
1005 return &bi->param_aa_statuses[index];
1009 /* Get AA status structure for the given BB and parameter with INDEX. Allocate
1010 structures and/or intialize the result with a dominating description as
1011 necessary. */
1013 static struct ipa_param_aa_status *
1014 parm_bb_aa_status_for_bb (struct ipa_func_body_info *fbi, basic_block bb,
1015 int index)
1017 gcc_checking_assert (fbi);
1018 struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
1019 if (bi->param_aa_statuses.is_empty ())
1020 bi->param_aa_statuses.safe_grow_cleared (fbi->param_count, true);
1021 struct ipa_param_aa_status *paa = &bi->param_aa_statuses[index];
1022 if (!paa->valid)
1024 gcc_checking_assert (!paa->parm_modified
1025 && !paa->ref_modified
1026 && !paa->pt_modified);
1027 struct ipa_param_aa_status *dom_paa;
1028 dom_paa = find_dominating_aa_status (fbi, bb, index);
1029 if (dom_paa)
1030 *paa = *dom_paa;
1031 else
1032 paa->valid = true;
1035 return paa;
1038 /* Return true if a load from a formal parameter PARM_LOAD is known to retrieve
1039 a value known not to be modified in this function before reaching the
1040 statement STMT. FBI holds information about the function we have so far
1041 gathered but do not survive the summary building stage. */
1043 static bool
1044 parm_preserved_before_stmt_p (struct ipa_func_body_info *fbi, int index,
1045 gimple *stmt, tree parm_load)
1047 struct ipa_param_aa_status *paa;
1048 bool modified = false;
1049 ao_ref refd;
1051 tree base = get_base_address (parm_load);
1052 gcc_assert (TREE_CODE (base) == PARM_DECL);
1053 if (TREE_READONLY (base))
1054 return true;
1056 gcc_checking_assert (fbi);
1057 paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (stmt), index);
1058 if (paa->parm_modified || fbi->aa_walk_budget == 0)
1059 return false;
1061 gcc_checking_assert (gimple_vuse (stmt) != NULL_TREE);
1062 ao_ref_init (&refd, parm_load);
1063 int walked = walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified,
1064 &modified, NULL, NULL,
1065 fbi->aa_walk_budget);
1066 if (walked < 0)
1068 modified = true;
1069 fbi->aa_walk_budget = 0;
1071 else
1072 fbi->aa_walk_budget -= walked;
1073 if (paa && modified)
1074 paa->parm_modified = true;
1075 return !modified;
1078 /* If STMT is an assignment that loads a value from an parameter declaration,
1079 return the index of the parameter in ipa_node_params which has not been
1080 modified. Otherwise return -1. */
1082 static int
1083 load_from_unmodified_param (struct ipa_func_body_info *fbi,
1084 vec<ipa_param_descriptor, va_gc> *descriptors,
1085 gimple *stmt)
1087 int index;
1088 tree op1;
1090 if (!gimple_assign_single_p (stmt))
1091 return -1;
1093 op1 = gimple_assign_rhs1 (stmt);
1094 if (TREE_CODE (op1) != PARM_DECL)
1095 return -1;
1097 index = ipa_get_param_decl_index_1 (descriptors, op1);
1098 if (index < 0
1099 || !parm_preserved_before_stmt_p (fbi, index, stmt, op1))
1100 return -1;
1102 return index;
1105 /* Return true if memory reference REF (which must be a load through parameter
1106 with INDEX) loads data that are known to be unmodified in this function
1107 before reaching statement STMT. */
1109 static bool
1110 parm_ref_data_preserved_p (struct ipa_func_body_info *fbi,
1111 int index, gimple *stmt, tree ref)
1113 struct ipa_param_aa_status *paa;
1114 bool modified = false;
1115 ao_ref refd;
1117 gcc_checking_assert (fbi);
1118 paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (stmt), index);
1119 if (paa->ref_modified || fbi->aa_walk_budget == 0)
1120 return false;
1122 gcc_checking_assert (gimple_vuse (stmt));
1123 ao_ref_init (&refd, ref);
1124 int walked = walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified,
1125 &modified, NULL, NULL,
1126 fbi->aa_walk_budget);
1127 if (walked < 0)
1129 modified = true;
1130 fbi->aa_walk_budget = 0;
1132 else
1133 fbi->aa_walk_budget -= walked;
1134 if (modified)
1135 paa->ref_modified = true;
1136 return !modified;
1139 /* Return true if the data pointed to by PARM (which is a parameter with INDEX)
1140 is known to be unmodified in this function before reaching call statement
1141 CALL into which it is passed. FBI describes the function body. */
1143 static bool
1144 parm_ref_data_pass_through_p (struct ipa_func_body_info *fbi, int index,
1145 gimple *call, tree parm)
1147 bool modified = false;
1148 ao_ref refd;
1150 /* It's unnecessary to calculate anything about memory contnets for a const
1151 function because it is not goin to use it. But do not cache the result
1152 either. Also, no such calculations for non-pointers. */
1153 if (!gimple_vuse (call)
1154 || !POINTER_TYPE_P (TREE_TYPE (parm)))
1155 return false;
1157 struct ipa_param_aa_status *paa = parm_bb_aa_status_for_bb (fbi,
1158 gimple_bb (call),
1159 index);
1160 if (paa->pt_modified || fbi->aa_walk_budget == 0)
1161 return false;
1163 ao_ref_init_from_ptr_and_size (&refd, parm, NULL_TREE);
1164 int walked = walk_aliased_vdefs (&refd, gimple_vuse (call), mark_modified,
1165 &modified, NULL, NULL,
1166 fbi->aa_walk_budget);
1167 if (walked < 0)
1169 fbi->aa_walk_budget = 0;
1170 modified = true;
1172 else
1173 fbi->aa_walk_budget -= walked;
1174 if (modified)
1175 paa->pt_modified = true;
1176 return !modified;
1179 /* Return true if we can prove that OP is a memory reference loading
1180 data from an aggregate passed as a parameter.
1182 The function works in two modes. If GUARANTEED_UNMODIFIED is NULL, it return
1183 false if it cannot prove that the value has not been modified before the
1184 load in STMT. If GUARANTEED_UNMODIFIED is not NULL, it will return true even
1185 if it cannot prove the value has not been modified, in that case it will
1186 store false to *GUARANTEED_UNMODIFIED, otherwise it will store true there.
1188 INFO and PARMS_AINFO describe parameters of the current function (but the
1189 latter can be NULL), STMT is the load statement. If function returns true,
1190 *INDEX_P, *OFFSET_P and *BY_REF is filled with the parameter index, offset
1191 within the aggregate and whether it is a load from a value passed by
1192 reference respectively.
1194 Return false if the offset divided by BITS_PER_UNIT would not fit into an
1195 unsigned int. */
1197 bool
1198 ipa_load_from_parm_agg (struct ipa_func_body_info *fbi,
1199 vec<ipa_param_descriptor, va_gc> *descriptors,
1200 gimple *stmt, tree op, int *index_p,
1201 HOST_WIDE_INT *offset_p, poly_int64 *size_p,
1202 bool *by_ref_p, bool *guaranteed_unmodified)
1204 int index;
1205 HOST_WIDE_INT size;
1206 bool reverse;
1207 tree base = get_ref_base_and_extent_hwi (op, offset_p, &size, &reverse);
1209 if (!base
1210 || (*offset_p / BITS_PER_UNIT) > UINT_MAX)
1211 return false;
1213 /* We can not propagate across volatile loads. */
1214 if (TREE_THIS_VOLATILE (op))
1215 return false;
1217 if (DECL_P (base))
1219 int index = ipa_get_param_decl_index_1 (descriptors, base);
1220 if (index >= 0
1221 && parm_preserved_before_stmt_p (fbi, index, stmt, op))
1223 *index_p = index;
1224 *by_ref_p = false;
1225 if (size_p)
1226 *size_p = size;
1227 if (guaranteed_unmodified)
1228 *guaranteed_unmodified = true;
1229 return true;
1231 return false;
1234 if (TREE_CODE (base) != MEM_REF
1235 || TREE_CODE (TREE_OPERAND (base, 0)) != SSA_NAME
1236 || !integer_zerop (TREE_OPERAND (base, 1)))
1237 return false;
1239 if (SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (base, 0)))
1241 tree parm = SSA_NAME_VAR (TREE_OPERAND (base, 0));
1242 index = ipa_get_param_decl_index_1 (descriptors, parm);
1244 else
1246 /* This branch catches situations where a pointer parameter is not a
1247 gimple register, for example:
1249 void hip7(S*) (struct S * p)
1251 void (*<T2e4>) (struct S *) D.1867;
1252 struct S * p.1;
1254 <bb 2>:
1255 p.1_1 = p;
1256 D.1867_2 = p.1_1->f;
1257 D.1867_2 ();
1258 gdp = &p;
1261 gimple *def = SSA_NAME_DEF_STMT (TREE_OPERAND (base, 0));
1262 index = load_from_unmodified_param (fbi, descriptors, def);
1265 if (index >= 0)
1267 bool data_preserved = parm_ref_data_preserved_p (fbi, index, stmt, op);
1268 if (!data_preserved && !guaranteed_unmodified)
1269 return false;
1271 *index_p = index;
1272 *by_ref_p = true;
1273 if (size_p)
1274 *size_p = size;
1275 if (guaranteed_unmodified)
1276 *guaranteed_unmodified = data_preserved;
1277 return true;
1279 return false;
1282 /* If STMT is an assignment that loads a value from a parameter declaration,
1283 or from an aggregate passed as the parameter either by value or reference,
1284 return the index of the parameter in ipa_node_params. Otherwise return -1.
1286 FBI holds gathered information about the function. INFO describes
1287 parameters of the function, STMT is the assignment statement. If it is a
1288 memory load from an aggregate, *OFFSET_P is filled with offset within the
1289 aggregate, and *BY_REF_P specifies whether the aggregate is passed by
1290 reference. */
1292 static int
1293 load_from_unmodified_param_or_agg (struct ipa_func_body_info *fbi,
1294 class ipa_node_params *info,
1295 gimple *stmt,
1296 HOST_WIDE_INT *offset_p,
1297 bool *by_ref_p)
1299 int index = load_from_unmodified_param (fbi, info->descriptors, stmt);
1300 poly_int64 size;
1302 /* Load value from a parameter declaration. */
1303 if (index >= 0)
1305 *offset_p = -1;
1306 return index;
1309 if (!gimple_assign_load_p (stmt))
1310 return -1;
1312 tree rhs = gimple_assign_rhs1 (stmt);
1314 /* Skip memory reference containing VIEW_CONVERT_EXPR. */
1315 for (tree t = rhs; handled_component_p (t); t = TREE_OPERAND (t, 0))
1316 if (TREE_CODE (t) == VIEW_CONVERT_EXPR)
1317 return -1;
1319 /* Skip memory reference containing bit-field. */
1320 if (TREE_CODE (rhs) == BIT_FIELD_REF
1321 || contains_bitfld_component_ref_p (rhs))
1322 return -1;
1324 if (!ipa_load_from_parm_agg (fbi, info->descriptors, stmt, rhs, &index,
1325 offset_p, &size, by_ref_p))
1326 return -1;
1328 gcc_assert (!maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (rhs))),
1329 size));
1330 if (!*by_ref_p)
1332 tree param_type = ipa_get_type (info, index);
1334 if (!param_type || !AGGREGATE_TYPE_P (param_type))
1335 return -1;
1337 else if (TREE_THIS_VOLATILE (rhs))
1338 return -1;
1340 return index;
1343 /* Walk pointer adjustemnts from OP (such as POINTER_PLUS and ADDR_EXPR)
1344 to find original pointer. Initialize RET to the pointer which results from
1345 the walk.
1346 If offset is known return true and initialize OFFSET_RET. */
1348 bool
1349 unadjusted_ptr_and_unit_offset (tree op, tree *ret, poly_int64 *offset_ret)
1351 poly_int64 offset = 0;
1352 bool offset_known = true;
1353 int i;
1355 for (i = 0; i < param_ipa_jump_function_lookups; i++)
1357 if (TREE_CODE (op) == ADDR_EXPR)
1359 poly_int64 extra_offset = 0;
1360 tree base = get_addr_base_and_unit_offset (TREE_OPERAND (op, 0),
1361 &offset);
1362 if (!base)
1364 base = get_base_address (TREE_OPERAND (op, 0));
1365 if (TREE_CODE (base) != MEM_REF)
1366 break;
1367 offset_known = false;
1369 else
1371 if (TREE_CODE (base) != MEM_REF)
1372 break;
1373 offset += extra_offset;
1375 op = TREE_OPERAND (base, 0);
1376 if (mem_ref_offset (base).to_shwi (&extra_offset))
1377 offset += extra_offset;
1378 else
1379 offset_known = false;
1381 else if (TREE_CODE (op) == SSA_NAME
1382 && !SSA_NAME_IS_DEFAULT_DEF (op))
1384 gimple *pstmt = SSA_NAME_DEF_STMT (op);
1386 if (gimple_assign_single_p (pstmt))
1387 op = gimple_assign_rhs1 (pstmt);
1388 else if (is_gimple_assign (pstmt)
1389 && gimple_assign_rhs_code (pstmt) == POINTER_PLUS_EXPR)
1391 poly_int64 extra_offset = 0;
1392 if (ptrdiff_tree_p (gimple_assign_rhs2 (pstmt),
1393 &extra_offset))
1394 offset += extra_offset;
1395 else
1396 offset_known = false;
1397 op = gimple_assign_rhs1 (pstmt);
1399 else
1400 break;
1402 else
1403 break;
1405 *ret = op;
1406 *offset_ret = offset;
1407 return offset_known;
1410 /* Given that an actual argument is an SSA_NAME (given in NAME) and is a result
1411 of an assignment statement STMT, try to determine whether we are actually
1412 handling any of the following cases and construct an appropriate jump
1413 function into JFUNC if so:
1415 1) The passed value is loaded from a formal parameter which is not a gimple
1416 register (most probably because it is addressable, the value has to be
1417 scalar) and we can guarantee the value has not changed. This case can
1418 therefore be described by a simple pass-through jump function. For example:
1420 foo (int a)
1422 int a.0;
1424 a.0_2 = a;
1425 bar (a.0_2);
1427 2) The passed value can be described by a simple arithmetic pass-through
1428 jump function. E.g.
1430 foo (int a)
1432 int D.2064;
1434 D.2064_4 = a.1(D) + 4;
1435 bar (D.2064_4);
1437 This case can also occur in combination of the previous one, e.g.:
1439 foo (int a, int z)
1441 int a.0;
1442 int D.2064;
1444 a.0_3 = a;
1445 D.2064_4 = a.0_3 + 4;
1446 foo (D.2064_4);
1448 3) The passed value is an address of an object within another one (which
1449 also passed by reference). Such situations are described by an ancestor
1450 jump function and describe situations such as:
1452 B::foo() (struct B * const this)
1454 struct A * D.1845;
1456 D.1845_2 = &this_1(D)->D.1748;
1457 A::bar (D.1845_2);
1459 INFO is the structure describing individual parameters access different
1460 stages of IPA optimizations. PARMS_AINFO contains the information that is
1461 only needed for intraprocedural analysis. */
1463 static void
1464 compute_complex_assign_jump_func (struct ipa_func_body_info *fbi,
1465 class ipa_node_params *info,
1466 struct ipa_jump_func *jfunc,
1467 gcall *call, gimple *stmt, tree name,
1468 tree param_type)
1470 HOST_WIDE_INT offset, size;
1471 tree op1, tc_ssa, base, ssa;
1472 bool reverse;
1473 int index;
1475 op1 = gimple_assign_rhs1 (stmt);
1477 if (TREE_CODE (op1) == SSA_NAME)
1479 if (SSA_NAME_IS_DEFAULT_DEF (op1))
1480 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (op1));
1481 else
1482 index = load_from_unmodified_param (fbi, info->descriptors,
1483 SSA_NAME_DEF_STMT (op1));
1484 tc_ssa = op1;
1486 else
1488 index = load_from_unmodified_param (fbi, info->descriptors, stmt);
1489 tc_ssa = gimple_assign_lhs (stmt);
1492 if (index >= 0)
1494 switch (gimple_assign_rhs_class (stmt))
1496 case GIMPLE_BINARY_RHS:
1498 tree op2 = gimple_assign_rhs2 (stmt);
1499 if (!is_gimple_ip_invariant (op2)
1500 || ((TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))
1501 != tcc_comparison)
1502 && !useless_type_conversion_p (TREE_TYPE (name),
1503 TREE_TYPE (op1))))
1504 return;
1506 ipa_set_jf_arith_pass_through (jfunc, index, op2,
1507 gimple_assign_rhs_code (stmt));
1508 break;
1510 case GIMPLE_SINGLE_RHS:
1512 bool agg_p = parm_ref_data_pass_through_p (fbi, index, call,
1513 tc_ssa);
1514 ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
1515 break;
1517 case GIMPLE_UNARY_RHS:
1518 if (!CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt)))
1519 ipa_set_jf_unary_pass_through (jfunc, index,
1520 gimple_assign_rhs_code (stmt));
1521 default:;
1523 return;
1526 if (TREE_CODE (op1) != ADDR_EXPR)
1527 return;
1528 op1 = TREE_OPERAND (op1, 0);
1529 base = get_ref_base_and_extent_hwi (op1, &offset, &size, &reverse);
1530 offset_int mem_offset;
1531 if (!base
1532 || TREE_CODE (base) != MEM_REF
1533 || !mem_ref_offset (base).is_constant (&mem_offset))
1534 return;
1535 offset += mem_offset.to_short_addr () * BITS_PER_UNIT;
1536 ssa = TREE_OPERAND (base, 0);
1537 if (TREE_CODE (ssa) != SSA_NAME
1538 || !SSA_NAME_IS_DEFAULT_DEF (ssa)
1539 || offset < 0)
1540 return;
1542 /* Dynamic types are changed in constructors and destructors. */
1543 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (ssa));
1544 if (index >= 0 && param_type && POINTER_TYPE_P (param_type))
1545 ipa_set_ancestor_jf (jfunc, offset, index,
1546 parm_ref_data_pass_through_p (fbi, index, call, ssa),
1547 false);
1550 /* Extract the base, offset and MEM_REF expression from a statement ASSIGN if
1551 it looks like:
1553 iftmp.1_3 = &obj_2(D)->D.1762;
1555 The base of the MEM_REF must be a default definition SSA NAME of a
1556 parameter. Return NULL_TREE if it looks otherwise. If case of success, the
1557 whole MEM_REF expression is returned and the offset calculated from any
1558 handled components and the MEM_REF itself is stored into *OFFSET. The whole
1559 RHS stripped off the ADDR_EXPR is stored into *OBJ_P. */
1561 static tree
1562 get_ancestor_addr_info (gimple *assign, tree *obj_p, HOST_WIDE_INT *offset)
1564 HOST_WIDE_INT size;
1565 tree expr, parm, obj;
1566 bool reverse;
1568 if (!gimple_assign_single_p (assign))
1569 return NULL_TREE;
1570 expr = gimple_assign_rhs1 (assign);
1572 if (TREE_CODE (expr) != ADDR_EXPR)
1573 return NULL_TREE;
1574 expr = TREE_OPERAND (expr, 0);
1575 obj = expr;
1576 expr = get_ref_base_and_extent_hwi (expr, offset, &size, &reverse);
1578 offset_int mem_offset;
1579 if (!expr
1580 || TREE_CODE (expr) != MEM_REF
1581 || !mem_ref_offset (expr).is_constant (&mem_offset))
1582 return NULL_TREE;
1583 parm = TREE_OPERAND (expr, 0);
1584 if (TREE_CODE (parm) != SSA_NAME
1585 || !SSA_NAME_IS_DEFAULT_DEF (parm)
1586 || TREE_CODE (SSA_NAME_VAR (parm)) != PARM_DECL)
1587 return NULL_TREE;
1589 *offset += mem_offset.to_short_addr () * BITS_PER_UNIT;
1590 *obj_p = obj;
1591 return expr;
1595 /* Given that an actual argument is an SSA_NAME that is a result of a phi
1596 statement PHI, try to find out whether NAME is in fact a
1597 multiple-inheritance typecast from a descendant into an ancestor of a formal
1598 parameter and thus can be described by an ancestor jump function and if so,
1599 write the appropriate function into JFUNC.
1601 Essentially we want to match the following pattern:
1603 if (obj_2(D) != 0B)
1604 goto <bb 3>;
1605 else
1606 goto <bb 4>;
1608 <bb 3>:
1609 iftmp.1_3 = &obj_2(D)->D.1762;
1611 <bb 4>:
1612 # iftmp.1_1 = PHI <iftmp.1_3(3), 0B(2)>
1613 D.1879_6 = middleman_1 (iftmp.1_1, i_5(D));
1614 return D.1879_6; */
1616 static void
1617 compute_complex_ancestor_jump_func (struct ipa_func_body_info *fbi,
1618 class ipa_node_params *info,
1619 struct ipa_jump_func *jfunc,
1620 gcall *call, gphi *phi)
1622 HOST_WIDE_INT offset;
1623 gimple *assign;
1624 basic_block phi_bb, assign_bb, cond_bb;
1625 tree tmp, parm, expr, obj;
1626 int index, i;
1628 if (gimple_phi_num_args (phi) != 2)
1629 return;
1631 if (integer_zerop (PHI_ARG_DEF (phi, 1)))
1632 tmp = PHI_ARG_DEF (phi, 0);
1633 else if (integer_zerop (PHI_ARG_DEF (phi, 0)))
1634 tmp = PHI_ARG_DEF (phi, 1);
1635 else
1636 return;
1637 if (TREE_CODE (tmp) != SSA_NAME
1638 || SSA_NAME_IS_DEFAULT_DEF (tmp)
1639 || !POINTER_TYPE_P (TREE_TYPE (tmp))
1640 || TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) != RECORD_TYPE)
1641 return;
1643 assign = SSA_NAME_DEF_STMT (tmp);
1644 assign_bb = gimple_bb (assign);
1645 if (!single_pred_p (assign_bb))
1646 return;
1647 expr = get_ancestor_addr_info (assign, &obj, &offset);
1648 if (!expr)
1649 return;
1650 parm = TREE_OPERAND (expr, 0);
1651 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (parm));
1652 if (index < 0)
1653 return;
1655 cond_bb = single_pred (assign_bb);
1656 gcond *cond = safe_dyn_cast <gcond *> (*gsi_last_bb (cond_bb));
1657 if (!cond
1658 || gimple_cond_code (cond) != NE_EXPR
1659 || gimple_cond_lhs (cond) != parm
1660 || !integer_zerop (gimple_cond_rhs (cond)))
1661 return;
1663 phi_bb = gimple_bb (phi);
1664 for (i = 0; i < 2; i++)
1666 basic_block pred = EDGE_PRED (phi_bb, i)->src;
1667 if (pred != assign_bb && pred != cond_bb)
1668 return;
1671 ipa_set_ancestor_jf (jfunc, offset, index,
1672 parm_ref_data_pass_through_p (fbi, index, call, parm),
1673 true);
1676 /* Inspect the given TYPE and return true iff it has the same structure (the
1677 same number of fields of the same types) as a C++ member pointer. If
1678 METHOD_PTR and DELTA are non-NULL, store the trees representing the
1679 corresponding fields there. */
1681 static bool
1682 type_like_member_ptr_p (tree type, tree *method_ptr, tree *delta)
1684 tree fld;
1686 if (TREE_CODE (type) != RECORD_TYPE)
1687 return false;
1689 fld = TYPE_FIELDS (type);
1690 if (!fld || !POINTER_TYPE_P (TREE_TYPE (fld))
1691 || TREE_CODE (TREE_TYPE (TREE_TYPE (fld))) != METHOD_TYPE
1692 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
1693 return false;
1695 if (method_ptr)
1696 *method_ptr = fld;
1698 fld = DECL_CHAIN (fld);
1699 if (!fld || INTEGRAL_TYPE_P (fld)
1700 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
1701 return false;
1702 if (delta)
1703 *delta = fld;
1705 if (DECL_CHAIN (fld))
1706 return false;
1708 return true;
1711 /* If RHS is an SSA_NAME and it is defined by a simple copy assign statement,
1712 return the rhs of its defining statement, and this statement is stored in
1713 *RHS_STMT. Otherwise return RHS as it is. */
1715 static inline tree
1716 get_ssa_def_if_simple_copy (tree rhs, gimple **rhs_stmt)
1718 while (TREE_CODE (rhs) == SSA_NAME && !SSA_NAME_IS_DEFAULT_DEF (rhs))
1720 gimple *def_stmt = SSA_NAME_DEF_STMT (rhs);
1722 if (gimple_assign_single_p (def_stmt))
1723 rhs = gimple_assign_rhs1 (def_stmt);
1724 else
1725 break;
1726 *rhs_stmt = def_stmt;
1728 return rhs;
1731 /* Simple linked list, describing contents of an aggregate before call. */
1733 struct ipa_known_agg_contents_list
1735 /* Offset and size of the described part of the aggregate. */
1736 HOST_WIDE_INT offset, size;
1738 /* Type of the described part of the aggregate. */
1739 tree type;
1741 /* Known constant value or jump function data describing contents. */
1742 struct ipa_load_agg_data value;
1744 /* Pointer to the next structure in the list. */
1745 struct ipa_known_agg_contents_list *next;
1748 /* Add an aggregate content item into a linked list of
1749 ipa_known_agg_contents_list structure, in which all elements
1750 are sorted ascendingly by offset. */
1752 static inline void
1753 add_to_agg_contents_list (struct ipa_known_agg_contents_list **plist,
1754 struct ipa_known_agg_contents_list *item)
1756 struct ipa_known_agg_contents_list *list = *plist;
1758 for (; list; list = list->next)
1760 if (list->offset >= item->offset)
1761 break;
1763 plist = &list->next;
1766 item->next = list;
1767 *plist = item;
1770 /* Check whether a given aggregate content is clobbered by certain element in
1771 a linked list of ipa_known_agg_contents_list. */
1773 static inline bool
1774 clobber_by_agg_contents_list_p (struct ipa_known_agg_contents_list *list,
1775 struct ipa_known_agg_contents_list *item)
1777 for (; list; list = list->next)
1779 if (list->offset >= item->offset)
1780 return list->offset < item->offset + item->size;
1782 if (list->offset + list->size > item->offset)
1783 return true;
1786 return false;
1789 /* Build aggregate jump function from LIST, assuming there are exactly
1790 VALUE_COUNT entries there and that offset of the passed argument
1791 is ARG_OFFSET and store it into JFUNC. */
1793 static void
1794 build_agg_jump_func_from_list (struct ipa_known_agg_contents_list *list,
1795 int value_count, HOST_WIDE_INT arg_offset,
1796 struct ipa_jump_func *jfunc)
1798 vec_safe_reserve (jfunc->agg.items, value_count, true);
1799 for (; list; list = list->next)
1801 struct ipa_agg_jf_item item;
1802 tree operand = list->value.pass_through.operand;
1804 if (list->value.pass_through.formal_id >= 0)
1806 /* Content value is derived from some formal paramerter. */
1807 if (list->value.offset >= 0)
1808 item.jftype = IPA_JF_LOAD_AGG;
1809 else
1810 item.jftype = IPA_JF_PASS_THROUGH;
1812 item.value.load_agg = list->value;
1813 if (operand)
1814 item.value.pass_through.operand
1815 = unshare_expr_without_location (operand);
1817 else if (operand)
1819 /* Content value is known constant. */
1820 item.jftype = IPA_JF_CONST;
1821 item.value.constant = unshare_expr_without_location (operand);
1823 else
1824 continue;
1826 item.type = list->type;
1827 gcc_assert (tree_to_shwi (TYPE_SIZE (list->type)) == list->size);
1829 item.offset = list->offset - arg_offset;
1830 gcc_assert ((item.offset % BITS_PER_UNIT) == 0);
1832 jfunc->agg.items->quick_push (item);
1836 /* Given an assignment statement STMT, try to collect information into
1837 AGG_VALUE that will be used to construct jump function for RHS of the
1838 assignment, from which content value of an aggregate part comes.
1840 Besides constant and simple pass-through jump functions, also try to
1841 identify whether it matches the following pattern that can be described by
1842 a load-value-from-aggregate jump function, which is a derivative of simple
1843 pass-through jump function.
1845 foo (int *p)
1849 *(q_5 + 4) = *(p_3(D) + 28) op 1;
1850 bar (q_5);
1853 Here IPA_LOAD_AGG_DATA data structure is informative enough to describe
1854 constant, simple pass-through and load-vale-from-aggregate. If value
1855 is constant, it will be kept in field OPERAND, and field FORMAL_ID is
1856 set to -1. For simple pass-through and load-value-from-aggregate, field
1857 FORMAL_ID specifies the related formal parameter index, and field
1858 OFFSET can be used to distinguish them, -1 means simple pass-through,
1859 otherwise means load-value-from-aggregate. */
1861 static void
1862 analyze_agg_content_value (struct ipa_func_body_info *fbi,
1863 struct ipa_load_agg_data *agg_value,
1864 gimple *stmt)
1866 tree lhs = gimple_assign_lhs (stmt);
1867 tree rhs1 = gimple_assign_rhs1 (stmt);
1868 enum tree_code code;
1869 int index = -1;
1871 /* Initialize jump function data for the aggregate part. */
1872 memset (agg_value, 0, sizeof (*agg_value));
1873 agg_value->pass_through.operation = NOP_EXPR;
1874 agg_value->pass_through.formal_id = -1;
1875 agg_value->offset = -1;
1877 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs)) /* TODO: Support aggregate type. */
1878 || TREE_THIS_VOLATILE (lhs)
1879 || TREE_CODE (lhs) == BIT_FIELD_REF
1880 || contains_bitfld_component_ref_p (lhs))
1881 return;
1883 /* Skip SSA copies. */
1884 while (gimple_assign_rhs_class (stmt) == GIMPLE_SINGLE_RHS)
1886 if (TREE_CODE (rhs1) != SSA_NAME || SSA_NAME_IS_DEFAULT_DEF (rhs1))
1887 break;
1889 stmt = SSA_NAME_DEF_STMT (rhs1);
1890 if (!is_gimple_assign (stmt))
1891 break;
1893 rhs1 = gimple_assign_rhs1 (stmt);
1896 if (gphi *phi = dyn_cast<gphi *> (stmt))
1898 /* Also special case like the following (a is a formal parameter):
1900 _12 = *a_11(D).dim[0].stride;
1902 # iftmp.22_9 = PHI <_12(2), 1(3)>
1904 parm.6.dim[0].stride = iftmp.22_9;
1906 __x_MOD_foo (&parm.6, b_31(D));
1908 The aggregate function describing parm.6.dim[0].stride is encoded as a
1909 PASS-THROUGH jump function with ASSERT_EXPR operation whith operand 1
1910 (the constant from the PHI node). */
1912 if (gimple_phi_num_args (phi) != 2)
1913 return;
1914 tree arg0 = gimple_phi_arg_def (phi, 0);
1915 tree arg1 = gimple_phi_arg_def (phi, 1);
1916 tree operand;
1918 if (is_gimple_ip_invariant (arg1))
1920 operand = arg1;
1921 rhs1 = arg0;
1923 else if (is_gimple_ip_invariant (arg0))
1925 operand = arg0;
1926 rhs1 = arg1;
1928 else
1929 return;
1931 rhs1 = get_ssa_def_if_simple_copy (rhs1, &stmt);
1932 if (!is_gimple_assign (stmt))
1933 return;
1935 code = ASSERT_EXPR;
1936 agg_value->pass_through.operand = operand;
1938 else if (is_gimple_assign (stmt))
1940 code = gimple_assign_rhs_code (stmt);
1941 switch (gimple_assign_rhs_class (stmt))
1943 case GIMPLE_SINGLE_RHS:
1944 if (is_gimple_ip_invariant (rhs1))
1946 agg_value->pass_through.operand = rhs1;
1947 return;
1949 code = NOP_EXPR;
1950 break;
1952 case GIMPLE_UNARY_RHS:
1953 /* NOTE: A GIMPLE_UNARY_RHS operation might not be tcc_unary
1954 (truth_not_expr is example), GIMPLE_BINARY_RHS does not imply
1955 tcc_binary, this subtleness is somewhat misleading.
1957 Since tcc_unary is widely used in IPA-CP code to check an operation
1958 with one operand, here we only allow tc_unary operation to avoid
1959 possible problem. Then we can use (opclass == tc_unary) or not to
1960 distinguish unary and binary. */
1961 if (TREE_CODE_CLASS (code) != tcc_unary || CONVERT_EXPR_CODE_P (code))
1962 return;
1964 rhs1 = get_ssa_def_if_simple_copy (rhs1, &stmt);
1965 break;
1967 case GIMPLE_BINARY_RHS:
1969 gimple *rhs1_stmt = stmt;
1970 gimple *rhs2_stmt = stmt;
1971 tree rhs2 = gimple_assign_rhs2 (stmt);
1973 rhs1 = get_ssa_def_if_simple_copy (rhs1, &rhs1_stmt);
1974 rhs2 = get_ssa_def_if_simple_copy (rhs2, &rhs2_stmt);
1976 if (is_gimple_ip_invariant (rhs2))
1978 agg_value->pass_through.operand = rhs2;
1979 stmt = rhs1_stmt;
1981 else if (is_gimple_ip_invariant (rhs1))
1983 if (TREE_CODE_CLASS (code) == tcc_comparison)
1984 code = swap_tree_comparison (code);
1985 else if (!commutative_tree_code (code))
1986 return;
1988 agg_value->pass_through.operand = rhs1;
1989 stmt = rhs2_stmt;
1990 rhs1 = rhs2;
1992 else
1993 return;
1995 if (TREE_CODE_CLASS (code) != tcc_comparison
1996 && !useless_type_conversion_p (TREE_TYPE (lhs),
1997 TREE_TYPE (rhs1)))
1998 return;
2000 break;
2002 default:
2003 return;
2006 else
2007 return;
2009 if (TREE_CODE (rhs1) != SSA_NAME)
2010 index = load_from_unmodified_param_or_agg (fbi, fbi->info, stmt,
2011 &agg_value->offset,
2012 &agg_value->by_ref);
2013 else if (SSA_NAME_IS_DEFAULT_DEF (rhs1))
2014 index = ipa_get_param_decl_index (fbi->info, SSA_NAME_VAR (rhs1));
2016 if (index >= 0)
2018 if (agg_value->offset >= 0)
2019 agg_value->type = TREE_TYPE (rhs1);
2020 agg_value->pass_through.formal_id = index;
2021 agg_value->pass_through.operation = code;
2023 else
2024 agg_value->pass_through.operand = NULL_TREE;
2027 /* If STMT is a memory store to the object whose address is BASE, extract
2028 information (offset, size, and value) into CONTENT, and return true,
2029 otherwise we conservatively assume the whole object is modified with
2030 unknown content, and return false. CHECK_REF means that access to object
2031 is expected to be in form of MEM_REF expression. */
2033 static bool
2034 extract_mem_content (struct ipa_func_body_info *fbi,
2035 gimple *stmt, tree base, bool check_ref,
2036 struct ipa_known_agg_contents_list *content)
2038 HOST_WIDE_INT lhs_offset, lhs_size;
2039 bool reverse;
2041 if (!is_gimple_assign (stmt))
2042 return false;
2044 tree lhs = gimple_assign_lhs (stmt);
2045 tree lhs_base = get_ref_base_and_extent_hwi (lhs, &lhs_offset, &lhs_size,
2046 &reverse);
2047 if (!lhs_base)
2048 return false;
2050 if (check_ref)
2052 if (TREE_CODE (lhs_base) != MEM_REF
2053 || TREE_OPERAND (lhs_base, 0) != base
2054 || !integer_zerop (TREE_OPERAND (lhs_base, 1)))
2055 return false;
2057 else if (lhs_base != base)
2058 return false;
2060 content->offset = lhs_offset;
2061 content->size = lhs_size;
2062 content->type = TREE_TYPE (lhs);
2063 content->next = NULL;
2065 analyze_agg_content_value (fbi, &content->value, stmt);
2066 return true;
2069 /* Traverse statements from CALL backwards, scanning whether an aggregate given
2070 in ARG is filled in constants or values that are derived from caller's
2071 formal parameter in the way described by some kinds of jump functions. FBI
2072 is the context of the caller function for interprocedural analysis. ARG can
2073 either be an aggregate expression or a pointer to an aggregate. ARG_TYPE is
2074 the type of the aggregate, JFUNC is the jump function for the aggregate. */
2076 static void
2077 determine_known_aggregate_parts (struct ipa_func_body_info *fbi,
2078 gcall *call, tree arg,
2079 tree arg_type,
2080 struct ipa_jump_func *jfunc)
2082 struct ipa_known_agg_contents_list *list = NULL, *all_list = NULL;
2083 bitmap visited = NULL;
2084 int item_count = 0, value_count = 0;
2085 HOST_WIDE_INT arg_offset, arg_size;
2086 tree arg_base;
2087 bool check_ref, by_ref;
2088 ao_ref r;
2089 int max_agg_items = opt_for_fn (fbi->node->decl, param_ipa_max_agg_items);
2091 if (max_agg_items == 0)
2092 return;
2094 /* The function operates in three stages. First, we prepare check_ref, r,
2095 arg_base and arg_offset based on what is actually passed as an actual
2096 argument. */
2098 if (POINTER_TYPE_P (arg_type))
2100 by_ref = true;
2101 if (TREE_CODE (arg) == SSA_NAME)
2103 tree type_size;
2104 if (!tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (arg_type)))
2105 || !POINTER_TYPE_P (TREE_TYPE (arg)))
2106 return;
2107 check_ref = true;
2108 arg_base = arg;
2109 arg_offset = 0;
2110 type_size = TYPE_SIZE (TREE_TYPE (arg_type));
2111 arg_size = tree_to_uhwi (type_size);
2112 ao_ref_init_from_ptr_and_size (&r, arg_base, NULL_TREE);
2114 else if (TREE_CODE (arg) == ADDR_EXPR)
2116 bool reverse;
2118 arg = TREE_OPERAND (arg, 0);
2119 arg_base = get_ref_base_and_extent_hwi (arg, &arg_offset,
2120 &arg_size, &reverse);
2121 if (!arg_base)
2122 return;
2123 if (DECL_P (arg_base))
2125 check_ref = false;
2126 ao_ref_init (&r, arg_base);
2128 else
2129 return;
2131 else
2132 return;
2134 else
2136 bool reverse;
2138 gcc_checking_assert (AGGREGATE_TYPE_P (TREE_TYPE (arg)));
2140 by_ref = false;
2141 check_ref = false;
2142 arg_base = get_ref_base_and_extent_hwi (arg, &arg_offset,
2143 &arg_size, &reverse);
2144 if (!arg_base)
2145 return;
2147 ao_ref_init (&r, arg);
2150 /* Second stage traverses virtual SSA web backwards starting from the call
2151 statement, only looks at individual dominating virtual operand (its
2152 definition dominates the call), as long as it is confident that content
2153 of the aggregate is affected by definition of the virtual operand, it
2154 builds a sorted linked list of ipa_agg_jf_list describing that. */
2156 for (tree dom_vuse = gimple_vuse (call);
2157 dom_vuse && fbi->aa_walk_budget > 0;)
2159 gimple *stmt = SSA_NAME_DEF_STMT (dom_vuse);
2161 if (gimple_code (stmt) == GIMPLE_PHI)
2163 dom_vuse = get_continuation_for_phi (stmt, &r, true,
2164 fbi->aa_walk_budget,
2165 &visited, false, NULL, NULL);
2166 continue;
2169 fbi->aa_walk_budget--;
2170 if (stmt_may_clobber_ref_p_1 (stmt, &r))
2172 struct ipa_known_agg_contents_list *content
2173 = XALLOCA (struct ipa_known_agg_contents_list);
2175 if (!extract_mem_content (fbi, stmt, arg_base, check_ref, content))
2176 break;
2178 /* Now we get a dominating virtual operand, and need to check
2179 whether its value is clobbered any other dominating one. */
2180 if ((content->value.pass_through.formal_id >= 0
2181 || content->value.pass_through.operand)
2182 && !clobber_by_agg_contents_list_p (all_list, content)
2183 /* Since IPA-CP stores results with unsigned int offsets, we can
2184 discard those which would not fit now before we stream them to
2185 WPA. */
2186 && (content->offset + content->size - arg_offset
2187 <= (HOST_WIDE_INT) UINT_MAX * BITS_PER_UNIT))
2189 struct ipa_known_agg_contents_list *copy
2190 = XALLOCA (struct ipa_known_agg_contents_list);
2192 /* Add to the list consisting of only dominating virtual
2193 operands, whose definitions can finally reach the call. */
2194 add_to_agg_contents_list (&list, (*copy = *content, copy));
2196 if (++value_count == max_agg_items)
2197 break;
2200 /* Add to the list consisting of all dominating virtual operands. */
2201 add_to_agg_contents_list (&all_list, content);
2203 if (++item_count == 2 * max_agg_items)
2204 break;
2206 dom_vuse = gimple_vuse (stmt);
2209 if (visited)
2210 BITMAP_FREE (visited);
2212 /* Third stage just goes over the list and creates an appropriate vector of
2213 ipa_agg_jf_item structures out of it, of course only if there are
2214 any meaningful items to begin with. */
2216 if (value_count)
2218 jfunc->agg.by_ref = by_ref;
2219 build_agg_jump_func_from_list (list, value_count, arg_offset, jfunc);
2224 /* Return the Ith param type of callee associated with call graph
2225 edge E. */
2227 tree
2228 ipa_get_callee_param_type (struct cgraph_edge *e, int i)
2230 int n;
2231 tree type = (e->callee
2232 ? TREE_TYPE (e->callee->decl)
2233 : gimple_call_fntype (e->call_stmt));
2234 tree t = TYPE_ARG_TYPES (type);
2236 for (n = 0; n < i; n++)
2238 if (!t)
2239 break;
2240 t = TREE_CHAIN (t);
2242 if (t && t != void_list_node)
2243 return TREE_VALUE (t);
2244 if (!e->callee)
2245 return NULL;
2246 t = DECL_ARGUMENTS (e->callee->decl);
2247 for (n = 0; n < i; n++)
2249 if (!t)
2250 return NULL;
2251 t = TREE_CHAIN (t);
2253 if (t)
2254 return TREE_TYPE (t);
2255 return NULL;
2258 /* Return a pointer to an ipa_vr just like TMP, but either find it in
2259 ipa_vr_hash_table or allocate it in GC memory. */
2261 static ipa_vr *
2262 ipa_get_value_range (const vrange &tmp)
2264 inchash::hash hstate;
2265 inchash::add_vrange (tmp, hstate);
2266 hashval_t hash = hstate.end ();
2267 ipa_vr **slot = ipa_vr_hash_table->find_slot_with_hash (&tmp, hash, INSERT);
2268 if (*slot)
2269 return *slot;
2271 ipa_vr *vr = new (ggc_alloc<ipa_vr> ()) ipa_vr (tmp);
2272 *slot = vr;
2273 return vr;
2276 /* Assign to JF a pointer to a range just like TMP but either fetch a
2277 copy from ipa_vr_hash_table or allocate a new on in GC memory. */
2279 static void
2280 ipa_set_jfunc_vr (ipa_jump_func *jf, const vrange &tmp)
2282 jf->m_vr = ipa_get_value_range (tmp);
2285 static void
2286 ipa_set_jfunc_vr (ipa_jump_func *jf, const ipa_vr &vr)
2288 Value_Range tmp;
2289 vr.get_vrange (tmp);
2290 ipa_set_jfunc_vr (jf, tmp);
2293 /* Compute jump function for all arguments of callsite CS and insert the
2294 information in the jump_functions array in the ipa_edge_args corresponding
2295 to this callsite. */
2297 static void
2298 ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
2299 struct cgraph_edge *cs)
2301 ipa_node_params *info = ipa_node_params_sum->get (cs->caller);
2302 ipa_edge_args *args = ipa_edge_args_sum->get_create (cs);
2303 gcall *call = cs->call_stmt;
2304 int n, arg_num = gimple_call_num_args (call);
2305 bool useful_context = false;
2307 if (arg_num == 0 || args->jump_functions)
2308 return;
2309 vec_safe_grow_cleared (args->jump_functions, arg_num, true);
2310 if (flag_devirtualize)
2311 vec_safe_grow_cleared (args->polymorphic_call_contexts, arg_num, true);
2313 if (gimple_call_internal_p (call))
2314 return;
2315 if (ipa_func_spec_opts_forbid_analysis_p (cs->caller))
2316 return;
2318 for (n = 0; n < arg_num; n++)
2320 struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, n);
2321 tree arg = gimple_call_arg (call, n);
2322 tree param_type = ipa_get_callee_param_type (cs, n);
2323 if (flag_devirtualize && POINTER_TYPE_P (TREE_TYPE (arg)))
2325 tree instance;
2326 class ipa_polymorphic_call_context context (cs->caller->decl,
2327 arg, cs->call_stmt,
2328 &instance);
2329 context.get_dynamic_type (instance, arg, NULL, cs->call_stmt,
2330 &fbi->aa_walk_budget);
2331 *ipa_get_ith_polymorhic_call_context (args, n) = context;
2332 if (!context.useless_p ())
2333 useful_context = true;
2336 Value_Range vr (TREE_TYPE (arg));
2337 if (POINTER_TYPE_P (TREE_TYPE (arg)))
2339 bool addr_nonzero = false;
2340 bool strict_overflow = false;
2342 if (TREE_CODE (arg) == SSA_NAME
2343 && param_type
2344 && get_range_query (cfun)->range_of_expr (vr, arg, cs->call_stmt)
2345 && vr.nonzero_p ())
2346 addr_nonzero = true;
2347 else if (tree_single_nonzero_warnv_p (arg, &strict_overflow))
2348 addr_nonzero = true;
2350 if (addr_nonzero)
2351 vr.set_nonzero (TREE_TYPE (arg));
2353 unsigned HOST_WIDE_INT bitpos;
2354 unsigned align, prec = TYPE_PRECISION (TREE_TYPE (arg));
2356 get_pointer_alignment_1 (arg, &align, &bitpos);
2358 if (align > BITS_PER_UNIT
2359 && opt_for_fn (cs->caller->decl, flag_ipa_bit_cp))
2361 wide_int mask
2362 = wi::bit_and_not (wi::mask (prec, false, prec),
2363 wide_int::from (align / BITS_PER_UNIT - 1,
2364 prec, UNSIGNED));
2365 wide_int value = wide_int::from (bitpos / BITS_PER_UNIT, prec,
2366 UNSIGNED);
2367 irange_bitmask bm (value, mask);
2368 if (!addr_nonzero)
2369 vr.set_varying (TREE_TYPE (arg));
2370 irange &r = as_a <irange> (vr);
2371 r.update_bitmask (bm);
2372 ipa_set_jfunc_vr (jfunc, vr);
2374 else if (addr_nonzero)
2375 ipa_set_jfunc_vr (jfunc, vr);
2376 else
2377 gcc_assert (!jfunc->m_vr);
2379 else
2381 if (param_type
2382 && Value_Range::supports_type_p (TREE_TYPE (arg))
2383 && Value_Range::supports_type_p (param_type)
2384 && irange::supports_p (TREE_TYPE (arg))
2385 && irange::supports_p (param_type)
2386 && get_range_query (cfun)->range_of_expr (vr, arg, cs->call_stmt)
2387 && !vr.undefined_p ())
2389 Value_Range resvr (vr);
2390 range_cast (resvr, param_type);
2391 if (!resvr.undefined_p () && !resvr.varying_p ())
2392 ipa_set_jfunc_vr (jfunc, resvr);
2393 else
2394 gcc_assert (!jfunc->m_vr);
2396 else
2397 gcc_assert (!jfunc->m_vr);
2400 if (is_gimple_ip_invariant (arg)
2401 || (VAR_P (arg)
2402 && is_global_var (arg)
2403 && TREE_READONLY (arg)))
2404 ipa_set_jf_constant (jfunc, arg, cs);
2405 else if (!is_gimple_reg_type (TREE_TYPE (arg))
2406 && TREE_CODE (arg) == PARM_DECL)
2408 int index = ipa_get_param_decl_index (info, arg);
2410 gcc_assert (index >=0);
2411 /* Aggregate passed by value, check for pass-through, otherwise we
2412 will attempt to fill in aggregate contents later in this
2413 for cycle. */
2414 if (parm_preserved_before_stmt_p (fbi, index, call, arg))
2416 ipa_set_jf_simple_pass_through (jfunc, index, false);
2417 continue;
2420 else if (TREE_CODE (arg) == SSA_NAME)
2422 if (SSA_NAME_IS_DEFAULT_DEF (arg))
2424 int index = ipa_get_param_decl_index (info, SSA_NAME_VAR (arg));
2425 if (index >= 0)
2427 bool agg_p;
2428 agg_p = parm_ref_data_pass_through_p (fbi, index, call, arg);
2429 ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
2432 else
2434 gimple *stmt = SSA_NAME_DEF_STMT (arg);
2435 if (is_gimple_assign (stmt))
2436 compute_complex_assign_jump_func (fbi, info, jfunc,
2437 call, stmt, arg, param_type);
2438 else if (gimple_code (stmt) == GIMPLE_PHI)
2439 compute_complex_ancestor_jump_func (fbi, info, jfunc,
2440 call,
2441 as_a <gphi *> (stmt));
2445 /* If ARG is pointer, we cannot use its type to determine the type of aggregate
2446 passed (because type conversions are ignored in gimple). Usually we can
2447 safely get type from function declaration, but in case of K&R prototypes or
2448 variadic functions we can try our luck with type of the pointer passed.
2449 TODO: Since we look for actual initialization of the memory object, we may better
2450 work out the type based on the memory stores we find. */
2451 if (!param_type)
2452 param_type = TREE_TYPE (arg);
2454 if ((jfunc->type != IPA_JF_PASS_THROUGH
2455 || !ipa_get_jf_pass_through_agg_preserved (jfunc))
2456 && (jfunc->type != IPA_JF_ANCESTOR
2457 || !ipa_get_jf_ancestor_agg_preserved (jfunc))
2458 && (AGGREGATE_TYPE_P (TREE_TYPE (arg))
2459 || POINTER_TYPE_P (param_type)))
2460 determine_known_aggregate_parts (fbi, call, arg, param_type, jfunc);
2462 if (!useful_context)
2463 vec_free (args->polymorphic_call_contexts);
2466 /* Compute jump functions for all edges - both direct and indirect - outgoing
2467 from BB. */
2469 static void
2470 ipa_compute_jump_functions_for_bb (struct ipa_func_body_info *fbi, basic_block bb)
2472 struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
2473 int i;
2474 struct cgraph_edge *cs;
2476 FOR_EACH_VEC_ELT_REVERSE (bi->cg_edges, i, cs)
2478 struct cgraph_node *callee = cs->callee;
2480 if (callee)
2482 callee = callee->ultimate_alias_target ();
2483 /* We do not need to bother analyzing calls to unknown functions
2484 unless they may become known during lto/whopr. */
2485 if (!callee->definition && !flag_lto
2486 && !gimple_call_fnspec (cs->call_stmt).known_p ())
2487 continue;
2489 ipa_compute_jump_functions_for_edge (fbi, cs);
2493 /* If STMT looks like a statement loading a value from a member pointer formal
2494 parameter, return that parameter and store the offset of the field to
2495 *OFFSET_P, if it is non-NULL. Otherwise return NULL (but *OFFSET_P still
2496 might be clobbered). If USE_DELTA, then we look for a use of the delta
2497 field rather than the pfn. */
2499 static tree
2500 ipa_get_stmt_member_ptr_load_param (gimple *stmt, bool use_delta,
2501 HOST_WIDE_INT *offset_p)
2503 tree rhs, fld, ptr_field, delta_field;
2504 tree ref_field = NULL_TREE;
2505 tree ref_offset = NULL_TREE;
2507 if (!gimple_assign_single_p (stmt))
2508 return NULL_TREE;
2510 rhs = gimple_assign_rhs1 (stmt);
2511 if (TREE_CODE (rhs) == COMPONENT_REF)
2513 ref_field = TREE_OPERAND (rhs, 1);
2514 rhs = TREE_OPERAND (rhs, 0);
2517 if (TREE_CODE (rhs) == MEM_REF)
2519 ref_offset = TREE_OPERAND (rhs, 1);
2520 if (ref_field && integer_nonzerop (ref_offset))
2521 return NULL_TREE;
2523 else if (!ref_field)
2524 return NULL_TREE;
2526 if (TREE_CODE (rhs) == MEM_REF
2527 && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
2528 && SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (rhs, 0)))
2530 rhs = TREE_OPERAND (rhs, 0);
2531 if (TREE_CODE (SSA_NAME_VAR (rhs)) != PARM_DECL
2532 || !type_like_member_ptr_p (TREE_TYPE (TREE_TYPE (rhs)), &ptr_field,
2533 &delta_field))
2534 return NULL_TREE;
2536 else
2538 if (TREE_CODE (rhs) == MEM_REF
2539 && TREE_CODE (TREE_OPERAND (rhs, 0)) == ADDR_EXPR)
2540 rhs = TREE_OPERAND (TREE_OPERAND (rhs, 0), 0);
2541 if (TREE_CODE (rhs) != PARM_DECL
2542 || !type_like_member_ptr_p (TREE_TYPE (rhs), &ptr_field,
2543 &delta_field))
2544 return NULL_TREE;
2547 if (use_delta)
2548 fld = delta_field;
2549 else
2550 fld = ptr_field;
2552 if (ref_field)
2554 if (ref_field != fld)
2555 return NULL_TREE;
2557 else if (!tree_int_cst_equal (byte_position (fld), ref_offset))
2558 return NULL_TREE;
2560 if (offset_p)
2561 *offset_p = int_bit_position (fld);
2562 return rhs;
2565 /* Returns true iff T is an SSA_NAME defined by a statement. */
2567 static bool
2568 ipa_is_ssa_with_stmt_def (tree t)
2570 if (TREE_CODE (t) == SSA_NAME
2571 && !SSA_NAME_IS_DEFAULT_DEF (t))
2572 return true;
2573 else
2574 return false;
2577 /* Find the indirect call graph edge corresponding to STMT and mark it as a
2578 call to a parameter number PARAM_INDEX. NODE is the caller. Return the
2579 indirect call graph edge.
2580 If POLYMORPHIC is true record is as a destination of polymorphic call. */
2582 static struct cgraph_edge *
2583 ipa_note_param_call (struct cgraph_node *node, int param_index,
2584 gcall *stmt, bool polymorphic)
2586 struct cgraph_edge *cs;
2588 cs = node->get_edge (stmt);
2589 cs->indirect_info->param_index = param_index;
2590 cs->indirect_info->agg_contents = 0;
2591 cs->indirect_info->member_ptr = 0;
2592 cs->indirect_info->guaranteed_unmodified = 0;
2593 ipa_node_params *info = ipa_node_params_sum->get (node);
2594 ipa_set_param_used_by_indirect_call (info, param_index, true);
2595 if (cs->indirect_info->polymorphic || polymorphic)
2596 ipa_set_param_used_by_polymorphic_call (info, param_index, true);
2597 return cs;
2600 /* Analyze the CALL and examine uses of formal parameters of the caller NODE
2601 (described by INFO). PARMS_AINFO is a pointer to a vector containing
2602 intermediate information about each formal parameter. Currently it checks
2603 whether the call calls a pointer that is a formal parameter and if so, the
2604 parameter is marked with the called flag and an indirect call graph edge
2605 describing the call is created. This is very simple for ordinary pointers
2606 represented in SSA but not-so-nice when it comes to member pointers. The
2607 ugly part of this function does nothing more than trying to match the
2608 pattern of such a call. Look up the documentation of macro
2609 TARGET_PTRMEMFUNC_VBIT_LOCATION for details. An example of such a pattern
2610 is the gimple dump below, the call is on the last line:
2612 <bb 2>:
2613 f$__delta_5 = f.__delta;
2614 f$__pfn_24 = f.__pfn;
2617 <bb 2>:
2618 f$__delta_5 = MEM[(struct *)&f];
2619 f$__pfn_24 = MEM[(struct *)&f + 4B];
2621 and a few lines below:
2623 <bb 5>
2624 D.2496_3 = (int) f$__pfn_24;
2625 D.2497_4 = D.2496_3 & 1;
2626 if (D.2497_4 != 0)
2627 goto <bb 3>;
2628 else
2629 goto <bb 4>;
2631 <bb 6>:
2632 D.2500_7 = (unsigned int) f$__delta_5;
2633 D.2501_8 = &S + D.2500_7;
2634 D.2502_9 = (int (*__vtbl_ptr_type) (void) * *) D.2501_8;
2635 D.2503_10 = *D.2502_9;
2636 D.2504_12 = f$__pfn_24 + -1;
2637 D.2505_13 = (unsigned int) D.2504_12;
2638 D.2506_14 = D.2503_10 + D.2505_13;
2639 D.2507_15 = *D.2506_14;
2640 iftmp.11_16 = (String:: *) D.2507_15;
2642 <bb 7>:
2643 # iftmp.11_1 = PHI <iftmp.11_16(3), f$__pfn_24(2)>
2644 D.2500_19 = (unsigned int) f$__delta_5;
2645 D.2508_20 = &S + D.2500_19;
2646 D.2493_21 = iftmp.11_1 (D.2508_20, 4);
2648 Such patterns are results of simple calls to a member pointer:
2650 int doprinting (int (MyString::* f)(int) const)
2652 MyString S ("somestring");
2654 return (S.*f)(4);
2657 Moreover, the function also looks for called pointers loaded from aggregates
2658 passed by value or reference. */
2660 static void
2661 ipa_analyze_indirect_call_uses (struct ipa_func_body_info *fbi, gcall *call,
2662 tree target)
2664 class ipa_node_params *info = fbi->info;
2665 HOST_WIDE_INT offset;
2666 bool by_ref;
2668 if (SSA_NAME_IS_DEFAULT_DEF (target))
2670 tree var = SSA_NAME_VAR (target);
2671 int index = ipa_get_param_decl_index (info, var);
2672 if (index >= 0)
2673 ipa_note_param_call (fbi->node, index, call, false);
2674 return;
2677 int index;
2678 gimple *def = SSA_NAME_DEF_STMT (target);
2679 bool guaranteed_unmodified;
2680 if (gimple_assign_single_p (def)
2681 && ipa_load_from_parm_agg (fbi, info->descriptors, def,
2682 gimple_assign_rhs1 (def), &index, &offset,
2683 NULL, &by_ref, &guaranteed_unmodified))
2685 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
2686 call, false);
2687 cs->indirect_info->offset = offset;
2688 cs->indirect_info->agg_contents = 1;
2689 cs->indirect_info->by_ref = by_ref;
2690 cs->indirect_info->guaranteed_unmodified = guaranteed_unmodified;
2691 return;
2694 /* Now we need to try to match the complex pattern of calling a member
2695 pointer. */
2696 if (gimple_code (def) != GIMPLE_PHI
2697 || gimple_phi_num_args (def) != 2
2698 || !POINTER_TYPE_P (TREE_TYPE (target))
2699 || TREE_CODE (TREE_TYPE (TREE_TYPE (target))) != METHOD_TYPE)
2700 return;
2702 /* First, we need to check whether one of these is a load from a member
2703 pointer that is a parameter to this function. */
2704 tree n1 = PHI_ARG_DEF (def, 0);
2705 tree n2 = PHI_ARG_DEF (def, 1);
2706 if (!ipa_is_ssa_with_stmt_def (n1) || !ipa_is_ssa_with_stmt_def (n2))
2707 return;
2708 gimple *d1 = SSA_NAME_DEF_STMT (n1);
2709 gimple *d2 = SSA_NAME_DEF_STMT (n2);
2711 tree rec;
2712 basic_block bb, virt_bb;
2713 basic_block join = gimple_bb (def);
2714 if ((rec = ipa_get_stmt_member_ptr_load_param (d1, false, &offset)))
2716 if (ipa_get_stmt_member_ptr_load_param (d2, false, NULL))
2717 return;
2719 bb = EDGE_PRED (join, 0)->src;
2720 virt_bb = gimple_bb (d2);
2722 else if ((rec = ipa_get_stmt_member_ptr_load_param (d2, false, &offset)))
2724 bb = EDGE_PRED (join, 1)->src;
2725 virt_bb = gimple_bb (d1);
2727 else
2728 return;
2730 /* Second, we need to check that the basic blocks are laid out in the way
2731 corresponding to the pattern. */
2733 if (!single_pred_p (virt_bb) || !single_succ_p (virt_bb)
2734 || single_succ (virt_bb) != join)
2735 return;
2738 if (single_pred (virt_bb) != bb)
2740 /* In cases when the distinction between a normal and a virtual
2741 function is encoded in the delta field, the load of the
2742 actual non-virtual function pointer can be in its own BB. */
2744 if (!single_pred_p (bb) || !single_succ_p (bb))
2745 return;
2746 bb = single_pred (bb);
2747 if (bb != single_pred (virt_bb))
2748 return;
2751 /* Third, let's see that the branching is done depending on the least
2752 significant bit of the pfn. */
2754 gcond *branch = safe_dyn_cast <gcond *> (*gsi_last_bb (bb));
2755 if (!branch)
2756 return;
2758 if ((gimple_cond_code (branch) != NE_EXPR
2759 && gimple_cond_code (branch) != EQ_EXPR)
2760 || !integer_zerop (gimple_cond_rhs (branch)))
2761 return;
2763 tree cond = gimple_cond_lhs (branch);
2764 if (!ipa_is_ssa_with_stmt_def (cond))
2765 return;
2767 def = SSA_NAME_DEF_STMT (cond);
2768 if (!is_gimple_assign (def)
2769 || gimple_assign_rhs_code (def) != BIT_AND_EXPR
2770 || !integer_onep (gimple_assign_rhs2 (def)))
2771 return;
2773 cond = gimple_assign_rhs1 (def);
2774 if (!ipa_is_ssa_with_stmt_def (cond))
2775 return;
2777 def = SSA_NAME_DEF_STMT (cond);
2779 if (is_gimple_assign (def)
2780 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
2782 cond = gimple_assign_rhs1 (def);
2783 if (!ipa_is_ssa_with_stmt_def (cond))
2784 return;
2785 def = SSA_NAME_DEF_STMT (cond);
2788 tree rec2;
2789 rec2 = ipa_get_stmt_member_ptr_load_param (def,
2790 (TARGET_PTRMEMFUNC_VBIT_LOCATION
2791 == ptrmemfunc_vbit_in_delta),
2792 NULL);
2793 if (rec != rec2)
2794 return;
2796 if (TREE_CODE (rec) == SSA_NAME)
2798 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (rec));
2799 if (index < 0
2800 || !parm_ref_data_preserved_p (fbi, index, call,
2801 gimple_assign_rhs1 (def)))
2802 return;
2803 by_ref = true;
2805 else
2807 index = ipa_get_param_decl_index (info, rec);
2808 if (index < 0
2809 || !parm_preserved_before_stmt_p (fbi, index, call, rec))
2810 return;
2811 by_ref = false;
2814 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
2815 call, false);
2816 cs->indirect_info->offset = offset;
2817 cs->indirect_info->agg_contents = 1;
2818 cs->indirect_info->member_ptr = 1;
2819 cs->indirect_info->by_ref = by_ref;
2820 cs->indirect_info->guaranteed_unmodified = 1;
2822 return;
2825 /* Analyze a CALL to an OBJ_TYPE_REF which is passed in TARGET and if the
2826 object referenced in the expression is a formal parameter of the caller
2827 FBI->node (described by FBI->info), create a call note for the
2828 statement. */
2830 static void
2831 ipa_analyze_virtual_call_uses (struct ipa_func_body_info *fbi,
2832 gcall *call, tree target)
2834 tree obj = OBJ_TYPE_REF_OBJECT (target);
2835 int index;
2836 HOST_WIDE_INT anc_offset;
2838 if (!flag_devirtualize)
2839 return;
2841 if (TREE_CODE (obj) != SSA_NAME)
2842 return;
2844 class ipa_node_params *info = fbi->info;
2845 if (SSA_NAME_IS_DEFAULT_DEF (obj))
2847 if (TREE_CODE (SSA_NAME_VAR (obj)) != PARM_DECL)
2848 return;
2850 anc_offset = 0;
2851 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (obj));
2852 gcc_assert (index >= 0);
2853 if (detect_type_change_ssa (fbi, obj, obj_type_ref_class (target),
2854 call))
2855 return;
2857 else
2859 gimple *stmt = SSA_NAME_DEF_STMT (obj);
2860 tree expr;
2862 expr = get_ancestor_addr_info (stmt, &obj, &anc_offset);
2863 if (!expr)
2864 return;
2865 index = ipa_get_param_decl_index (info,
2866 SSA_NAME_VAR (TREE_OPERAND (expr, 0)));
2867 gcc_assert (index >= 0);
2868 if (detect_type_change (fbi, obj, expr, obj_type_ref_class (target),
2869 call, anc_offset))
2870 return;
2873 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
2874 call, true);
2875 class cgraph_indirect_call_info *ii = cs->indirect_info;
2876 ii->offset = anc_offset;
2877 ii->otr_token = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target));
2878 ii->otr_type = obj_type_ref_class (target);
2879 ii->polymorphic = 1;
2882 /* Analyze a call statement CALL whether and how it utilizes formal parameters
2883 of the caller (described by INFO). PARMS_AINFO is a pointer to a vector
2884 containing intermediate information about each formal parameter. */
2886 static void
2887 ipa_analyze_call_uses (struct ipa_func_body_info *fbi, gcall *call)
2889 tree target = gimple_call_fn (call);
2891 if (!target
2892 || (TREE_CODE (target) != SSA_NAME
2893 && !virtual_method_call_p (target)))
2894 return;
2896 struct cgraph_edge *cs = fbi->node->get_edge (call);
2897 /* If we previously turned the call into a direct call, there is
2898 no need to analyze. */
2899 if (cs && !cs->indirect_unknown_callee)
2900 return;
2902 if (cs->indirect_info->polymorphic && flag_devirtualize)
2904 tree instance;
2905 tree target = gimple_call_fn (call);
2906 ipa_polymorphic_call_context context (current_function_decl,
2907 target, call, &instance);
2909 gcc_checking_assert (cs->indirect_info->otr_type
2910 == obj_type_ref_class (target));
2911 gcc_checking_assert (cs->indirect_info->otr_token
2912 == tree_to_shwi (OBJ_TYPE_REF_TOKEN (target)));
2914 cs->indirect_info->vptr_changed
2915 = !context.get_dynamic_type (instance,
2916 OBJ_TYPE_REF_OBJECT (target),
2917 obj_type_ref_class (target), call,
2918 &fbi->aa_walk_budget);
2919 cs->indirect_info->context = context;
2922 if (TREE_CODE (target) == SSA_NAME)
2923 ipa_analyze_indirect_call_uses (fbi, call, target);
2924 else if (virtual_method_call_p (target))
2925 ipa_analyze_virtual_call_uses (fbi, call, target);
2929 /* Analyze the call statement STMT with respect to formal parameters (described
2930 in INFO) of caller given by FBI->NODE. Currently it only checks whether
2931 formal parameters are called. */
2933 static void
2934 ipa_analyze_stmt_uses (struct ipa_func_body_info *fbi, gimple *stmt)
2936 if (is_gimple_call (stmt))
2937 ipa_analyze_call_uses (fbi, as_a <gcall *> (stmt));
2940 /* Callback of walk_stmt_load_store_addr_ops for the visit_load.
2941 If OP is a parameter declaration, mark it as used in the info structure
2942 passed in DATA. */
2944 static bool
2945 visit_ref_for_mod_analysis (gimple *, tree op, tree, void *data)
2947 class ipa_node_params *info = (class ipa_node_params *) data;
2949 op = get_base_address (op);
2950 if (op
2951 && TREE_CODE (op) == PARM_DECL)
2953 int index = ipa_get_param_decl_index (info, op);
2954 gcc_assert (index >= 0);
2955 ipa_set_param_used (info, index, true);
2958 return false;
2961 /* Scan the statements in BB and inspect the uses of formal parameters. Store
2962 the findings in various structures of the associated ipa_node_params
2963 structure, such as parameter flags, notes etc. FBI holds various data about
2964 the function being analyzed. */
2966 static void
2967 ipa_analyze_params_uses_in_bb (struct ipa_func_body_info *fbi, basic_block bb)
2969 gimple_stmt_iterator gsi;
2970 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2972 gimple *stmt = gsi_stmt (gsi);
2974 if (is_gimple_debug (stmt))
2975 continue;
2977 ipa_analyze_stmt_uses (fbi, stmt);
2978 walk_stmt_load_store_addr_ops (stmt, fbi->info,
2979 visit_ref_for_mod_analysis,
2980 visit_ref_for_mod_analysis,
2981 visit_ref_for_mod_analysis);
2983 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2984 walk_stmt_load_store_addr_ops (gsi_stmt (gsi), fbi->info,
2985 visit_ref_for_mod_analysis,
2986 visit_ref_for_mod_analysis,
2987 visit_ref_for_mod_analysis);
2990 /* Return true EXPR is a load from a dereference of SSA_NAME NAME. */
2992 static bool
2993 load_from_dereferenced_name (tree expr, tree name)
2995 tree base = get_base_address (expr);
2996 return (TREE_CODE (base) == MEM_REF
2997 && TREE_OPERAND (base, 0) == name);
3000 /* Calculate controlled uses of parameters of NODE. */
3002 static void
3003 ipa_analyze_controlled_uses (struct cgraph_node *node)
3005 ipa_node_params *info = ipa_node_params_sum->get (node);
3007 for (int i = 0; i < ipa_get_param_count (info); i++)
3009 tree parm = ipa_get_param (info, i);
3010 int call_uses = 0;
3011 bool load_dereferenced = false;
3013 /* For SSA regs see if parameter is used. For non-SSA we compute
3014 the flag during modification analysis. */
3015 if (is_gimple_reg (parm))
3017 tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl),
3018 parm);
3019 if (ddef && !has_zero_uses (ddef))
3021 imm_use_iterator imm_iter;
3022 gimple *stmt;
3024 ipa_set_param_used (info, i, true);
3025 FOR_EACH_IMM_USE_STMT (stmt, imm_iter, ddef)
3027 if (is_gimple_debug (stmt))
3028 continue;
3030 int all_stmt_uses = 0;
3031 use_operand_p use_p;
3032 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
3033 all_stmt_uses++;
3035 if (is_gimple_call (stmt))
3037 if (gimple_call_internal_p (stmt))
3039 call_uses = IPA_UNDESCRIBED_USE;
3040 break;
3042 int recognized_stmt_uses;
3043 if (gimple_call_fn (stmt) == ddef)
3044 recognized_stmt_uses = 1;
3045 else
3046 recognized_stmt_uses = 0;
3047 unsigned arg_count = gimple_call_num_args (stmt);
3048 for (unsigned i = 0; i < arg_count; i++)
3050 tree arg = gimple_call_arg (stmt, i);
3051 if (arg == ddef)
3052 recognized_stmt_uses++;
3053 else if (load_from_dereferenced_name (arg, ddef))
3055 load_dereferenced = true;
3056 recognized_stmt_uses++;
3060 if (recognized_stmt_uses != all_stmt_uses)
3062 call_uses = IPA_UNDESCRIBED_USE;
3063 break;
3065 if (call_uses >= 0)
3066 call_uses += all_stmt_uses;
3068 else if (gimple_assign_single_p (stmt))
3070 tree rhs = gimple_assign_rhs1 (stmt);
3071 if (all_stmt_uses != 1
3072 || !load_from_dereferenced_name (rhs, ddef))
3074 call_uses = IPA_UNDESCRIBED_USE;
3075 break;
3077 load_dereferenced = true;
3079 else
3081 call_uses = IPA_UNDESCRIBED_USE;
3082 break;
3086 else
3087 call_uses = 0;
3089 else
3090 call_uses = IPA_UNDESCRIBED_USE;
3091 ipa_set_controlled_uses (info, i, call_uses);
3092 ipa_set_param_load_dereferenced (info, i, load_dereferenced);
3096 /* Free stuff in BI. */
3098 static void
3099 free_ipa_bb_info (struct ipa_bb_info *bi)
3101 bi->cg_edges.release ();
3102 bi->param_aa_statuses.release ();
3105 /* Dominator walker driving the analysis. */
3107 class analysis_dom_walker : public dom_walker
3109 public:
3110 analysis_dom_walker (struct ipa_func_body_info *fbi)
3111 : dom_walker (CDI_DOMINATORS), m_fbi (fbi) {}
3113 edge before_dom_children (basic_block) final override;
3115 private:
3116 struct ipa_func_body_info *m_fbi;
3119 edge
3120 analysis_dom_walker::before_dom_children (basic_block bb)
3122 ipa_analyze_params_uses_in_bb (m_fbi, bb);
3123 ipa_compute_jump_functions_for_bb (m_fbi, bb);
3124 return NULL;
3127 /* Release body info FBI. */
3129 void
3130 ipa_release_body_info (struct ipa_func_body_info *fbi)
3132 int i;
3133 struct ipa_bb_info *bi;
3135 FOR_EACH_VEC_ELT (fbi->bb_infos, i, bi)
3136 free_ipa_bb_info (bi);
3137 fbi->bb_infos.release ();
3140 /* Initialize the array describing properties of formal parameters
3141 of NODE, analyze their uses and compute jump functions associated
3142 with actual arguments of calls from within NODE. */
3144 void
3145 ipa_analyze_node (struct cgraph_node *node)
3147 struct ipa_func_body_info fbi;
3148 class ipa_node_params *info;
3150 ipa_check_create_node_params ();
3151 ipa_check_create_edge_args ();
3152 info = ipa_node_params_sum->get_create (node);
3154 if (info->analysis_done)
3155 return;
3156 info->analysis_done = 1;
3158 if (ipa_func_spec_opts_forbid_analysis_p (node)
3159 || (count_formal_params (node->decl)
3160 >= (1 << IPA_PROP_ARG_INDEX_LIMIT_BITS)))
3162 gcc_assert (!ipa_get_param_count (info));
3163 return;
3166 struct function *func = DECL_STRUCT_FUNCTION (node->decl);
3167 push_cfun (func);
3168 calculate_dominance_info (CDI_DOMINATORS);
3169 ipa_initialize_node_params (node);
3170 ipa_analyze_controlled_uses (node);
3172 fbi.node = node;
3173 fbi.info = info;
3174 fbi.bb_infos = vNULL;
3175 fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
3176 fbi.param_count = ipa_get_param_count (info);
3177 fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps);
3179 for (struct cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
3181 ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
3182 bi->cg_edges.safe_push (cs);
3185 for (struct cgraph_edge *cs = node->indirect_calls; cs; cs = cs->next_callee)
3187 ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
3188 bi->cg_edges.safe_push (cs);
3191 enable_ranger (cfun, false);
3192 analysis_dom_walker (&fbi).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
3193 disable_ranger (cfun);
3195 ipa_release_body_info (&fbi);
3196 free_dominance_info (CDI_DOMINATORS);
3197 pop_cfun ();
3200 /* Update the jump functions associated with call graph edge E when the call
3201 graph edge CS is being inlined, assuming that E->caller is already (possibly
3202 indirectly) inlined into CS->callee and that E has not been inlined. */
3204 static void
3205 update_jump_functions_after_inlining (struct cgraph_edge *cs,
3206 struct cgraph_edge *e)
3208 ipa_edge_args *top = ipa_edge_args_sum->get (cs);
3209 ipa_edge_args *args = ipa_edge_args_sum->get (e);
3210 if (!args)
3211 return;
3212 int count = ipa_get_cs_argument_count (args);
3213 int i;
3215 for (i = 0; i < count; i++)
3217 struct ipa_jump_func *dst = ipa_get_ith_jump_func (args, i);
3218 class ipa_polymorphic_call_context *dst_ctx
3219 = ipa_get_ith_polymorhic_call_context (args, i);
3221 if (dst->agg.items)
3223 struct ipa_agg_jf_item *item;
3224 int j;
3226 FOR_EACH_VEC_ELT (*dst->agg.items, j, item)
3228 int dst_fid;
3229 struct ipa_jump_func *src;
3231 if (item->jftype != IPA_JF_PASS_THROUGH
3232 && item->jftype != IPA_JF_LOAD_AGG)
3233 continue;
3235 dst_fid = item->value.pass_through.formal_id;
3236 if (!top || dst_fid >= ipa_get_cs_argument_count (top))
3238 item->jftype = IPA_JF_UNKNOWN;
3239 continue;
3242 item->value.pass_through.formal_id = -1;
3243 src = ipa_get_ith_jump_func (top, dst_fid);
3244 if (src->type == IPA_JF_CONST)
3246 if (item->jftype == IPA_JF_PASS_THROUGH
3247 && item->value.pass_through.operation == NOP_EXPR)
3249 item->jftype = IPA_JF_CONST;
3250 item->value.constant = src->value.constant.value;
3251 continue;
3254 else if (src->type == IPA_JF_PASS_THROUGH
3255 && src->value.pass_through.operation == NOP_EXPR)
3257 if (item->jftype == IPA_JF_PASS_THROUGH
3258 || !item->value.load_agg.by_ref
3259 || src->value.pass_through.agg_preserved)
3260 item->value.pass_through.formal_id
3261 = src->value.pass_through.formal_id;
3263 else if (src->type == IPA_JF_ANCESTOR)
3265 if (item->jftype == IPA_JF_PASS_THROUGH)
3267 if (!src->value.ancestor.offset)
3268 item->value.pass_through.formal_id
3269 = src->value.ancestor.formal_id;
3271 else if (src->value.ancestor.agg_preserved)
3273 gcc_checking_assert (item->value.load_agg.by_ref);
3275 item->value.pass_through.formal_id
3276 = src->value.ancestor.formal_id;
3277 item->value.load_agg.offset
3278 += src->value.ancestor.offset;
3282 if (item->value.pass_through.formal_id < 0)
3283 item->jftype = IPA_JF_UNKNOWN;
3287 if (!top)
3289 ipa_set_jf_unknown (dst);
3290 continue;
3293 if (dst->type == IPA_JF_ANCESTOR)
3295 struct ipa_jump_func *src;
3296 int dst_fid = dst->value.ancestor.formal_id;
3297 class ipa_polymorphic_call_context *src_ctx
3298 = ipa_get_ith_polymorhic_call_context (top, dst_fid);
3300 /* Variable number of arguments can cause havoc if we try to access
3301 one that does not exist in the inlined edge. So make sure we
3302 don't. */
3303 if (dst_fid >= ipa_get_cs_argument_count (top))
3305 ipa_set_jf_unknown (dst);
3306 continue;
3309 src = ipa_get_ith_jump_func (top, dst_fid);
3311 if (src_ctx && !src_ctx->useless_p ())
3313 class ipa_polymorphic_call_context ctx = *src_ctx;
3315 /* TODO: Make type preserved safe WRT contexts. */
3316 if (!ipa_get_jf_ancestor_type_preserved (dst))
3317 ctx.possible_dynamic_type_change (e->in_polymorphic_cdtor);
3318 ctx.offset_by (dst->value.ancestor.offset);
3319 if (!ctx.useless_p ())
3321 if (!dst_ctx)
3323 vec_safe_grow_cleared (args->polymorphic_call_contexts,
3324 count, true);
3325 dst_ctx = ipa_get_ith_polymorhic_call_context (args, i);
3328 dst_ctx->combine_with (ctx);
3332 /* Parameter and argument in ancestor jump function must be pointer
3333 type, which means access to aggregate must be by-reference. */
3334 gcc_assert (!src->agg.items || src->agg.by_ref);
3336 if (src->agg.items && dst->value.ancestor.agg_preserved)
3338 struct ipa_agg_jf_item *item;
3339 int j;
3341 /* Currently we do not produce clobber aggregate jump functions,
3342 replace with merging when we do. */
3343 gcc_assert (!dst->agg.items);
3345 dst->agg.items = vec_safe_copy (src->agg.items);
3346 dst->agg.by_ref = src->agg.by_ref;
3347 FOR_EACH_VEC_SAFE_ELT (dst->agg.items, j, item)
3348 item->offset -= dst->value.ancestor.offset;
3351 if (src->type == IPA_JF_PASS_THROUGH
3352 && src->value.pass_through.operation == NOP_EXPR)
3354 dst->value.ancestor.formal_id = src->value.pass_through.formal_id;
3355 dst->value.ancestor.agg_preserved &=
3356 src->value.pass_through.agg_preserved;
3358 else if (src->type == IPA_JF_ANCESTOR)
3360 dst->value.ancestor.formal_id = src->value.ancestor.formal_id;
3361 dst->value.ancestor.offset += src->value.ancestor.offset;
3362 dst->value.ancestor.agg_preserved &=
3363 src->value.ancestor.agg_preserved;
3364 dst->value.ancestor.keep_null |= src->value.ancestor.keep_null;
3366 else
3367 ipa_set_jf_unknown (dst);
3369 else if (dst->type == IPA_JF_PASS_THROUGH)
3371 struct ipa_jump_func *src;
3372 /* We must check range due to calls with variable number of arguments
3373 and we cannot combine jump functions with operations. */
3374 if (dst->value.pass_through.operation == NOP_EXPR
3375 && (top && dst->value.pass_through.formal_id
3376 < ipa_get_cs_argument_count (top)))
3378 int dst_fid = dst->value.pass_through.formal_id;
3379 src = ipa_get_ith_jump_func (top, dst_fid);
3380 bool dst_agg_p = ipa_get_jf_pass_through_agg_preserved (dst);
3381 class ipa_polymorphic_call_context *src_ctx
3382 = ipa_get_ith_polymorhic_call_context (top, dst_fid);
3384 if (src_ctx && !src_ctx->useless_p ())
3386 class ipa_polymorphic_call_context ctx = *src_ctx;
3388 /* TODO: Make type preserved safe WRT contexts. */
3389 if (!ipa_get_jf_pass_through_type_preserved (dst))
3390 ctx.possible_dynamic_type_change (e->in_polymorphic_cdtor);
3391 if (!ctx.useless_p ())
3393 if (!dst_ctx)
3395 vec_safe_grow_cleared (args->polymorphic_call_contexts,
3396 count, true);
3397 dst_ctx = ipa_get_ith_polymorhic_call_context (args, i);
3399 dst_ctx->combine_with (ctx);
3402 switch (src->type)
3404 case IPA_JF_UNKNOWN:
3405 ipa_set_jf_unknown (dst);
3406 break;
3407 case IPA_JF_CONST:
3409 bool rd = ipa_get_jf_pass_through_refdesc_decremented (dst);
3410 ipa_set_jf_cst_copy (dst, src);
3411 if (rd)
3412 ipa_zap_jf_refdesc (dst);
3415 break;
3417 case IPA_JF_PASS_THROUGH:
3419 int formal_id = ipa_get_jf_pass_through_formal_id (src);
3420 enum tree_code operation;
3421 operation = ipa_get_jf_pass_through_operation (src);
3423 if (operation == NOP_EXPR)
3425 bool agg_p;
3426 agg_p = dst_agg_p
3427 && ipa_get_jf_pass_through_agg_preserved (src);
3428 ipa_set_jf_simple_pass_through (dst, formal_id, agg_p);
3430 else if (TREE_CODE_CLASS (operation) == tcc_unary)
3431 ipa_set_jf_unary_pass_through (dst, formal_id, operation);
3432 else
3434 tree operand = ipa_get_jf_pass_through_operand (src);
3435 ipa_set_jf_arith_pass_through (dst, formal_id, operand,
3436 operation);
3438 break;
3440 case IPA_JF_ANCESTOR:
3442 bool agg_p;
3443 agg_p = dst_agg_p
3444 && ipa_get_jf_ancestor_agg_preserved (src);
3445 ipa_set_ancestor_jf (dst,
3446 ipa_get_jf_ancestor_offset (src),
3447 ipa_get_jf_ancestor_formal_id (src),
3448 agg_p,
3449 ipa_get_jf_ancestor_keep_null (src));
3450 break;
3452 default:
3453 gcc_unreachable ();
3456 if (src->agg.items
3457 && (dst_agg_p || !src->agg.by_ref))
3459 /* Currently we do not produce clobber aggregate jump
3460 functions, replace with merging when we do. */
3461 gcc_assert (!dst->agg.items);
3463 dst->agg.by_ref = src->agg.by_ref;
3464 dst->agg.items = vec_safe_copy (src->agg.items);
3467 else
3468 ipa_set_jf_unknown (dst);
3473 /* If TARGET is an addr_expr of a function declaration, make it the
3474 (SPECULATIVE)destination of an indirect edge IE and return the edge.
3475 Otherwise, return NULL. */
3477 struct cgraph_edge *
3478 ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
3479 bool speculative)
3481 struct cgraph_node *callee;
3482 bool unreachable = false;
3484 if (TREE_CODE (target) == ADDR_EXPR)
3485 target = TREE_OPERAND (target, 0);
3486 if (TREE_CODE (target) != FUNCTION_DECL)
3488 target = canonicalize_constructor_val (target, NULL);
3489 if (!target || TREE_CODE (target) != FUNCTION_DECL)
3491 /* Member pointer call that goes through a VMT lookup. */
3492 if (ie->indirect_info->member_ptr
3493 /* Or if target is not an invariant expression and we do not
3494 know if it will evaulate to function at runtime.
3495 This can happen when folding through &VAR, where &VAR
3496 is IP invariant, but VAR itself is not.
3498 TODO: Revisit this when GCC 5 is branched. It seems that
3499 member_ptr check is not needed and that we may try to fold
3500 the expression and see if VAR is readonly. */
3501 || !is_gimple_ip_invariant (target))
3503 if (dump_enabled_p ())
3505 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
3506 "discovered direct call non-invariant %s\n",
3507 ie->caller->dump_name ());
3509 return NULL;
3513 if (dump_enabled_p ())
3515 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
3516 "discovered direct call to non-function in %s, "
3517 "making it __builtin_unreachable\n",
3518 ie->caller->dump_name ());
3521 target = builtin_decl_unreachable ();
3522 callee = cgraph_node::get_create (target);
3523 unreachable = true;
3525 else
3526 callee = cgraph_node::get (target);
3528 else
3529 callee = cgraph_node::get (target);
3531 /* Because may-edges are not explicitely represented and vtable may be external,
3532 we may create the first reference to the object in the unit. */
3533 if (!callee || callee->inlined_to)
3536 /* We are better to ensure we can refer to it.
3537 In the case of static functions we are out of luck, since we already
3538 removed its body. In the case of public functions we may or may
3539 not introduce the reference. */
3540 if (!canonicalize_constructor_val (target, NULL)
3541 || !TREE_PUBLIC (target))
3543 if (dump_file)
3544 fprintf (dump_file, "ipa-prop: Discovered call to a known target "
3545 "(%s -> %s) but cannot refer to it. Giving up.\n",
3546 ie->caller->dump_name (),
3547 ie->callee->dump_name ());
3548 return NULL;
3550 callee = cgraph_node::get_create (target);
3553 /* If the edge is already speculated. */
3554 if (speculative && ie->speculative)
3556 if (dump_file)
3558 cgraph_edge *e2 = ie->speculative_call_for_target (callee);
3559 if (!e2)
3561 if (dump_file)
3562 fprintf (dump_file, "ipa-prop: Discovered call to a "
3563 "speculative target (%s -> %s) but the call is "
3564 "already speculated to different target. "
3565 "Giving up.\n",
3566 ie->caller->dump_name (), callee->dump_name ());
3568 else
3570 if (dump_file)
3571 fprintf (dump_file,
3572 "ipa-prop: Discovered call to a speculative target "
3573 "(%s -> %s) this agree with previous speculation.\n",
3574 ie->caller->dump_name (), callee->dump_name ());
3577 return NULL;
3580 if (!dbg_cnt (devirt))
3581 return NULL;
3583 ipa_check_create_node_params ();
3585 /* We cannot make edges to inline clones. It is bug that someone removed
3586 the cgraph node too early. */
3587 gcc_assert (!callee->inlined_to);
3589 if (dump_file && !unreachable)
3591 fprintf (dump_file, "ipa-prop: Discovered %s call to a %s target "
3592 "(%s -> %s), for stmt ",
3593 ie->indirect_info->polymorphic ? "a virtual" : "an indirect",
3594 speculative ? "speculative" : "known",
3595 ie->caller->dump_name (),
3596 callee->dump_name ());
3597 if (ie->call_stmt)
3598 print_gimple_stmt (dump_file, ie->call_stmt, 2, TDF_SLIM);
3599 else
3600 fprintf (dump_file, "with uid %i\n", ie->lto_stmt_uid);
3602 if (dump_enabled_p ())
3604 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
3605 "converting indirect call in %s to direct call to %s\n",
3606 ie->caller->dump_name (), callee->dump_name ());
3608 if (!speculative)
3610 struct cgraph_edge *orig = ie;
3611 ie = cgraph_edge::make_direct (ie, callee);
3612 /* If we resolved speculative edge the cost is already up to date
3613 for direct call (adjusted by inline_edge_duplication_hook). */
3614 if (ie == orig)
3616 ipa_call_summary *es = ipa_call_summaries->get (ie);
3617 es->call_stmt_size -= (eni_size_weights.indirect_call_cost
3618 - eni_size_weights.call_cost);
3619 es->call_stmt_time -= (eni_time_weights.indirect_call_cost
3620 - eni_time_weights.call_cost);
3623 else
3625 if (!callee->can_be_discarded_p ())
3627 cgraph_node *alias;
3628 alias = dyn_cast<cgraph_node *> (callee->noninterposable_alias ());
3629 if (alias)
3630 callee = alias;
3632 /* make_speculative will update ie's cost to direct call cost. */
3633 ie = ie->make_speculative
3634 (callee, ie->count.apply_scale (8, 10));
3637 return ie;
3640 /* Attempt to locate an interprocedural constant at a given REQ_OFFSET in
3641 CONSTRUCTOR and return it. Return NULL if the search fails for some
3642 reason. */
3644 static tree
3645 find_constructor_constant_at_offset (tree constructor, HOST_WIDE_INT req_offset)
3647 tree type = TREE_TYPE (constructor);
3648 if (TREE_CODE (type) != ARRAY_TYPE
3649 && TREE_CODE (type) != RECORD_TYPE)
3650 return NULL;
3652 unsigned ix;
3653 tree index, val;
3654 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (constructor), ix, index, val)
3656 HOST_WIDE_INT elt_offset;
3657 if (TREE_CODE (type) == ARRAY_TYPE)
3659 offset_int off;
3660 tree unit_size = TYPE_SIZE_UNIT (TREE_TYPE (type));
3661 gcc_assert (TREE_CODE (unit_size) == INTEGER_CST);
3663 if (index)
3665 if (TREE_CODE (index) == RANGE_EXPR)
3666 off = wi::to_offset (TREE_OPERAND (index, 0));
3667 else
3668 off = wi::to_offset (index);
3669 if (TYPE_DOMAIN (type) && TYPE_MIN_VALUE (TYPE_DOMAIN (type)))
3671 tree low_bound = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
3672 gcc_assert (TREE_CODE (unit_size) == INTEGER_CST);
3673 off = wi::sext (off - wi::to_offset (low_bound),
3674 TYPE_PRECISION (TREE_TYPE (index)));
3676 off *= wi::to_offset (unit_size);
3677 /* ??? Handle more than just the first index of a
3678 RANGE_EXPR. */
3680 else
3681 off = wi::to_offset (unit_size) * ix;
3683 off = wi::lshift (off, LOG2_BITS_PER_UNIT);
3684 if (!wi::fits_shwi_p (off) || wi::neg_p (off))
3685 continue;
3686 elt_offset = off.to_shwi ();
3688 else if (TREE_CODE (type) == RECORD_TYPE)
3690 gcc_checking_assert (index && TREE_CODE (index) == FIELD_DECL);
3691 if (DECL_BIT_FIELD (index))
3692 continue;
3693 elt_offset = int_bit_position (index);
3695 else
3696 gcc_unreachable ();
3698 if (elt_offset > req_offset)
3699 return NULL;
3701 if (TREE_CODE (val) == CONSTRUCTOR)
3702 return find_constructor_constant_at_offset (val,
3703 req_offset - elt_offset);
3705 if (elt_offset == req_offset
3706 && is_gimple_reg_type (TREE_TYPE (val))
3707 && is_gimple_ip_invariant (val))
3708 return val;
3710 return NULL;
3713 /* Check whether SCALAR could be used to look up an aggregate interprocedural
3714 invariant from a static constructor and if so, return it. Otherwise return
3715 NULL. */
3717 tree
3718 ipa_find_agg_cst_from_init (tree scalar, HOST_WIDE_INT offset, bool by_ref)
3720 if (by_ref)
3722 if (TREE_CODE (scalar) != ADDR_EXPR)
3723 return NULL;
3724 scalar = TREE_OPERAND (scalar, 0);
3727 if (!VAR_P (scalar)
3728 || !is_global_var (scalar)
3729 || !TREE_READONLY (scalar)
3730 || !DECL_INITIAL (scalar)
3731 || TREE_CODE (DECL_INITIAL (scalar)) != CONSTRUCTOR)
3732 return NULL;
3734 return find_constructor_constant_at_offset (DECL_INITIAL (scalar), offset);
3737 /* Retrieve value from AGG_JFUNC for the given OFFSET or return NULL if there
3738 is none. BY_REF specifies whether the value has to be passed by reference
3739 or by value. */
3741 static tree
3742 ipa_find_agg_cst_from_jfunc_items (struct ipa_agg_jump_function *agg_jfunc,
3743 ipa_node_params *src_info,
3744 cgraph_node *src_node,
3745 HOST_WIDE_INT offset, bool by_ref)
3747 if (by_ref != agg_jfunc->by_ref)
3748 return NULL_TREE;
3750 for (const ipa_agg_jf_item &item : agg_jfunc->items)
3751 if (item.offset == offset)
3752 return ipa_agg_value_from_jfunc (src_info, src_node, &item);
3754 return NULL_TREE;
3757 /* Remove a reference to SYMBOL from the list of references of a node given by
3758 reference description RDESC. Return true if the reference has been
3759 successfully found and removed. */
3761 static bool
3762 remove_described_reference (symtab_node *symbol, struct ipa_cst_ref_desc *rdesc)
3764 struct ipa_ref *to_del;
3765 struct cgraph_edge *origin;
3767 origin = rdesc->cs;
3768 if (!origin)
3769 return false;
3770 to_del = origin->caller->find_reference (symbol, origin->call_stmt,
3771 origin->lto_stmt_uid, IPA_REF_ADDR);
3772 if (!to_del)
3773 return false;
3775 to_del->remove_reference ();
3776 if (dump_file)
3777 fprintf (dump_file, "ipa-prop: Removed a reference from %s to %s.\n",
3778 origin->caller->dump_name (), symbol->dump_name ());
3779 return true;
3782 /* If JFUNC has a reference description with refcount different from
3783 IPA_UNDESCRIBED_USE, return the reference description, otherwise return
3784 NULL. JFUNC must be a constant jump function. */
3786 static struct ipa_cst_ref_desc *
3787 jfunc_rdesc_usable (struct ipa_jump_func *jfunc)
3789 struct ipa_cst_ref_desc *rdesc = ipa_get_jf_constant_rdesc (jfunc);
3790 if (rdesc && rdesc->refcount != IPA_UNDESCRIBED_USE)
3791 return rdesc;
3792 else
3793 return NULL;
3796 /* If the value of constant jump function JFUNC is an address of a function
3797 declaration, return the associated call graph node. Otherwise return
3798 NULL. */
3800 static symtab_node *
3801 symtab_node_for_jfunc (struct ipa_jump_func *jfunc)
3803 gcc_checking_assert (jfunc->type == IPA_JF_CONST);
3804 tree cst = ipa_get_jf_constant (jfunc);
3805 if (TREE_CODE (cst) != ADDR_EXPR
3806 || (TREE_CODE (TREE_OPERAND (cst, 0)) != FUNCTION_DECL
3807 && TREE_CODE (TREE_OPERAND (cst, 0)) != VAR_DECL))
3808 return NULL;
3810 return symtab_node::get (TREE_OPERAND (cst, 0));
3814 /* If JFUNC is a constant jump function with a usable rdesc, decrement its
3815 refcount and if it hits zero, remove reference to SYMBOL from the caller of
3816 the edge specified in the rdesc. Return false if either the symbol or the
3817 reference could not be found, otherwise return true. */
3819 static bool
3820 try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc)
3822 struct ipa_cst_ref_desc *rdesc;
3823 if (jfunc->type == IPA_JF_CONST
3824 && (rdesc = jfunc_rdesc_usable (jfunc))
3825 && --rdesc->refcount == 0)
3827 symtab_node *symbol = symtab_node_for_jfunc (jfunc);
3828 if (!symbol)
3829 return false;
3831 return remove_described_reference (symbol, rdesc);
3833 return true;
3836 /* Try to find a destination for indirect edge IE that corresponds to a simple
3837 call or a call of a member function pointer and where the destination is a
3838 pointer formal parameter described by jump function JFUNC. TARGET_TYPE is
3839 the type of the parameter to which the result of JFUNC is passed. If it can
3840 be determined, return the newly direct edge, otherwise return NULL.
3841 NEW_ROOT and NEW_ROOT_INFO is the node and its info that JFUNC lattices are
3842 relative to. */
3844 static struct cgraph_edge *
3845 try_make_edge_direct_simple_call (struct cgraph_edge *ie,
3846 struct ipa_jump_func *jfunc, tree target_type,
3847 struct cgraph_node *new_root,
3848 class ipa_node_params *new_root_info)
3850 struct cgraph_edge *cs;
3851 tree target = NULL_TREE;
3852 bool agg_contents = ie->indirect_info->agg_contents;
3853 tree scalar = ipa_value_from_jfunc (new_root_info, jfunc, target_type);
3854 if (agg_contents)
3856 if (scalar)
3857 target = ipa_find_agg_cst_from_init (scalar, ie->indirect_info->offset,
3858 ie->indirect_info->by_ref);
3859 if (!target && ie->indirect_info->guaranteed_unmodified)
3860 target = ipa_find_agg_cst_from_jfunc_items (&jfunc->agg, new_root_info,
3861 new_root,
3862 ie->indirect_info->offset,
3863 ie->indirect_info->by_ref);
3865 else
3866 target = scalar;
3867 if (!target)
3868 return NULL;
3869 cs = ipa_make_edge_direct_to_target (ie, target);
3871 if (cs && !agg_contents)
3873 bool ok;
3874 gcc_checking_assert (cs->callee
3875 && (cs != ie
3876 || jfunc->type != IPA_JF_CONST
3877 || !symtab_node_for_jfunc (jfunc)
3878 || cs->callee == symtab_node_for_jfunc (jfunc)));
3879 ok = try_decrement_rdesc_refcount (jfunc);
3880 gcc_checking_assert (ok);
3883 return cs;
3886 /* Return the target to be used in cases of impossible devirtualization. IE
3887 and target (the latter can be NULL) are dumped when dumping is enabled. */
3889 tree
3890 ipa_impossible_devirt_target (struct cgraph_edge *ie, tree target)
3892 if (dump_file)
3894 if (target)
3895 fprintf (dump_file,
3896 "Type inconsistent devirtualization: %s->%s\n",
3897 ie->caller->dump_name (),
3898 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (target)));
3899 else
3900 fprintf (dump_file,
3901 "No devirtualization target in %s\n",
3902 ie->caller->dump_name ());
3904 tree new_target = builtin_decl_unreachable ();
3905 cgraph_node::get_create (new_target);
3906 return new_target;
3909 /* Try to find a destination for indirect edge IE that corresponds to a virtual
3910 call based on a formal parameter which is described by jump function JFUNC
3911 and if it can be determined, make it direct and return the direct edge.
3912 Otherwise, return NULL. CTX describes the polymorphic context that the
3913 parameter the call is based on brings along with it. NEW_ROOT and
3914 NEW_ROOT_INFO is the node and its info that JFUNC lattices are relative
3915 to. */
3917 static struct cgraph_edge *
3918 try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
3919 struct ipa_jump_func *jfunc,
3920 class ipa_polymorphic_call_context ctx,
3921 struct cgraph_node *new_root,
3922 class ipa_node_params *new_root_info)
3924 tree target = NULL;
3925 bool speculative = false;
3927 if (!opt_for_fn (ie->caller->decl, flag_devirtualize))
3928 return NULL;
3930 gcc_assert (!ie->indirect_info->by_ref);
3932 /* Try to do lookup via known virtual table pointer value. */
3933 if (!ie->indirect_info->vptr_changed
3934 || opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively))
3936 tree vtable;
3937 unsigned HOST_WIDE_INT offset;
3938 tree t = NULL_TREE;
3939 if (jfunc->type == IPA_JF_CONST)
3940 t = ipa_find_agg_cst_from_init (ipa_get_jf_constant (jfunc),
3941 ie->indirect_info->offset, true);
3942 if (!t)
3943 t = ipa_find_agg_cst_from_jfunc_items (&jfunc->agg, new_root_info,
3944 new_root,
3945 ie->indirect_info->offset, true);
3946 if (t && vtable_pointer_value_to_vtable (t, &vtable, &offset))
3948 bool can_refer;
3949 t = gimple_get_virt_method_for_vtable (ie->indirect_info->otr_token,
3950 vtable, offset, &can_refer);
3951 if (can_refer)
3953 if (!t
3954 || fndecl_built_in_p (t, BUILT_IN_UNREACHABLE,
3955 BUILT_IN_UNREACHABLE_TRAP)
3956 || !possible_polymorphic_call_target_p
3957 (ie, cgraph_node::get (t)))
3959 /* Do not speculate builtin_unreachable, it is stupid! */
3960 if (!ie->indirect_info->vptr_changed)
3961 target = ipa_impossible_devirt_target (ie, target);
3962 else
3963 target = NULL;
3965 else
3967 target = t;
3968 speculative = ie->indirect_info->vptr_changed;
3974 ipa_polymorphic_call_context ie_context (ie);
3975 vec <cgraph_node *>targets;
3976 bool final;
3978 ctx.offset_by (ie->indirect_info->offset);
3979 if (ie->indirect_info->vptr_changed)
3980 ctx.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
3981 ie->indirect_info->otr_type);
3982 ctx.combine_with (ie_context, ie->indirect_info->otr_type);
3983 targets = possible_polymorphic_call_targets
3984 (ie->indirect_info->otr_type,
3985 ie->indirect_info->otr_token,
3986 ctx, &final);
3987 if (final && targets.length () <= 1)
3989 speculative = false;
3990 if (targets.length () == 1)
3991 target = targets[0]->decl;
3992 else
3993 target = ipa_impossible_devirt_target (ie, NULL_TREE);
3995 else if (!target && opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively)
3996 && !ie->speculative && ie->maybe_hot_p ())
3998 cgraph_node *n;
3999 n = try_speculative_devirtualization (ie->indirect_info->otr_type,
4000 ie->indirect_info->otr_token,
4001 ie->indirect_info->context);
4002 if (n)
4004 target = n->decl;
4005 speculative = true;
4009 if (target)
4011 if (!possible_polymorphic_call_target_p
4012 (ie, cgraph_node::get_create (target)))
4014 if (speculative)
4015 return NULL;
4016 target = ipa_impossible_devirt_target (ie, target);
4018 return ipa_make_edge_direct_to_target (ie, target, speculative);
4020 else
4021 return NULL;
4024 /* Update the param called notes associated with NODE when CS is being inlined,
4025 assuming NODE is (potentially indirectly) inlined into CS->callee.
4026 Moreover, if the callee is discovered to be constant, create a new cgraph
4027 edge for it. Newly discovered indirect edges will be added to *NEW_EDGES,
4028 unless NEW_EDGES is NULL. Return true iff a new edge(s) were created. */
4030 static bool
4031 update_indirect_edges_after_inlining (struct cgraph_edge *cs,
4032 struct cgraph_node *node,
4033 vec<cgraph_edge *> *new_edges)
4035 class ipa_edge_args *top;
4036 struct cgraph_edge *ie, *next_ie, *new_direct_edge;
4037 struct cgraph_node *new_root;
4038 class ipa_node_params *new_root_info, *inlined_node_info;
4039 bool res = false;
4041 ipa_check_create_edge_args ();
4042 top = ipa_edge_args_sum->get (cs);
4043 new_root = cs->caller->inlined_to
4044 ? cs->caller->inlined_to : cs->caller;
4045 new_root_info = ipa_node_params_sum->get (new_root);
4046 inlined_node_info = ipa_node_params_sum->get (cs->callee->function_symbol ());
4048 for (ie = node->indirect_calls; ie; ie = next_ie)
4050 class cgraph_indirect_call_info *ici = ie->indirect_info;
4051 struct ipa_jump_func *jfunc;
4052 int param_index;
4054 next_ie = ie->next_callee;
4056 if (ici->param_index == -1)
4057 continue;
4059 /* We must check range due to calls with variable number of arguments: */
4060 if (!top || ici->param_index >= ipa_get_cs_argument_count (top))
4062 ici->param_index = -1;
4063 continue;
4066 param_index = ici->param_index;
4067 jfunc = ipa_get_ith_jump_func (top, param_index);
4069 auto_vec<cgraph_node *, 4> spec_targets;
4070 if (ie->speculative)
4071 for (cgraph_edge *direct = ie->first_speculative_call_target ();
4072 direct;
4073 direct = direct->next_speculative_call_target ())
4074 spec_targets.safe_push (direct->callee);
4076 if (!opt_for_fn (node->decl, flag_indirect_inlining))
4077 new_direct_edge = NULL;
4078 else if (ici->polymorphic)
4080 ipa_polymorphic_call_context ctx;
4081 ctx = ipa_context_from_jfunc (new_root_info, cs, param_index, jfunc);
4082 new_direct_edge = try_make_edge_direct_virtual_call (ie, jfunc, ctx,
4083 new_root,
4084 new_root_info);
4086 else
4088 tree target_type = ipa_get_type (inlined_node_info, param_index);
4089 new_direct_edge = try_make_edge_direct_simple_call (ie, jfunc,
4090 target_type,
4091 new_root,
4092 new_root_info);
4095 /* If speculation was removed, then we need to do nothing. */
4096 if (new_direct_edge && new_direct_edge != ie
4097 && spec_targets.contains (new_direct_edge->callee))
4099 new_direct_edge->indirect_inlining_edge = 1;
4100 res = true;
4101 if (!new_direct_edge->speculative)
4102 continue;
4104 else if (new_direct_edge)
4106 new_direct_edge->indirect_inlining_edge = 1;
4107 if (new_edges)
4109 new_edges->safe_push (new_direct_edge);
4110 res = true;
4112 /* If speculative edge was introduced we still need to update
4113 call info of the indirect edge. */
4114 if (!new_direct_edge->speculative)
4115 continue;
4117 if (jfunc->type == IPA_JF_PASS_THROUGH
4118 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
4120 if (ici->agg_contents
4121 && !ipa_get_jf_pass_through_agg_preserved (jfunc)
4122 && !ici->polymorphic)
4123 ici->param_index = -1;
4124 else
4126 ici->param_index = ipa_get_jf_pass_through_formal_id (jfunc);
4127 if (ici->polymorphic
4128 && !ipa_get_jf_pass_through_type_preserved (jfunc))
4129 ici->vptr_changed = true;
4130 ipa_set_param_used_by_indirect_call (new_root_info,
4131 ici->param_index, true);
4132 if (ici->polymorphic)
4133 ipa_set_param_used_by_polymorphic_call (new_root_info,
4134 ici->param_index, true);
4137 else if (jfunc->type == IPA_JF_ANCESTOR)
4139 if (ici->agg_contents
4140 && !ipa_get_jf_ancestor_agg_preserved (jfunc)
4141 && !ici->polymorphic)
4142 ici->param_index = -1;
4143 else
4145 ici->param_index = ipa_get_jf_ancestor_formal_id (jfunc);
4146 ici->offset += ipa_get_jf_ancestor_offset (jfunc);
4147 if (ici->polymorphic
4148 && !ipa_get_jf_ancestor_type_preserved (jfunc))
4149 ici->vptr_changed = true;
4150 ipa_set_param_used_by_indirect_call (new_root_info,
4151 ici->param_index, true);
4152 if (ici->polymorphic)
4153 ipa_set_param_used_by_polymorphic_call (new_root_info,
4154 ici->param_index, true);
4157 else
4158 /* Either we can find a destination for this edge now or never. */
4159 ici->param_index = -1;
4162 return res;
4165 /* Recursively traverse subtree of NODE (including node) made of inlined
4166 cgraph_edges when CS has been inlined and invoke
4167 update_indirect_edges_after_inlining on all nodes and
4168 update_jump_functions_after_inlining on all non-inlined edges that lead out
4169 of this subtree. Newly discovered indirect edges will be added to
4170 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were
4171 created. */
4173 static bool
4174 propagate_info_to_inlined_callees (struct cgraph_edge *cs,
4175 struct cgraph_node *node,
4176 vec<cgraph_edge *> *new_edges)
4178 struct cgraph_edge *e;
4179 bool res;
4181 res = update_indirect_edges_after_inlining (cs, node, new_edges);
4183 for (e = node->callees; e; e = e->next_callee)
4184 if (!e->inline_failed)
4185 res |= propagate_info_to_inlined_callees (cs, e->callee, new_edges);
4186 else
4187 update_jump_functions_after_inlining (cs, e);
4188 for (e = node->indirect_calls; e; e = e->next_callee)
4189 update_jump_functions_after_inlining (cs, e);
4191 return res;
4194 /* Combine two controlled uses counts as done during inlining. */
4196 static int
4197 combine_controlled_uses_counters (int c, int d)
4199 if (c == IPA_UNDESCRIBED_USE || d == IPA_UNDESCRIBED_USE)
4200 return IPA_UNDESCRIBED_USE;
4201 else
4202 return c + d - 1;
4205 /* Propagate number of controlled users from CS->caleee to the new root of the
4206 tree of inlined nodes. */
4208 static void
4209 propagate_controlled_uses (struct cgraph_edge *cs)
4211 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
4212 if (!args)
4213 return;
4214 struct cgraph_node *new_root = cs->caller->inlined_to
4215 ? cs->caller->inlined_to : cs->caller;
4216 ipa_node_params *new_root_info = ipa_node_params_sum->get (new_root);
4217 ipa_node_params *old_root_info = ipa_node_params_sum->get (cs->callee);
4218 int count, i;
4220 if (!old_root_info)
4221 return;
4223 count = MIN (ipa_get_cs_argument_count (args),
4224 ipa_get_param_count (old_root_info));
4225 for (i = 0; i < count; i++)
4227 struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
4228 struct ipa_cst_ref_desc *rdesc;
4230 if (jf->type == IPA_JF_PASS_THROUGH
4231 && !ipa_get_jf_pass_through_refdesc_decremented (jf))
4233 int src_idx, c, d;
4234 src_idx = ipa_get_jf_pass_through_formal_id (jf);
4235 c = ipa_get_controlled_uses (new_root_info, src_idx);
4236 d = ipa_get_controlled_uses (old_root_info, i);
4238 gcc_checking_assert (ipa_get_jf_pass_through_operation (jf)
4239 == NOP_EXPR || c == IPA_UNDESCRIBED_USE);
4240 c = combine_controlled_uses_counters (c, d);
4241 ipa_set_controlled_uses (new_root_info, src_idx, c);
4242 bool lderef = true;
4243 if (c != IPA_UNDESCRIBED_USE)
4245 lderef = (ipa_get_param_load_dereferenced (new_root_info, src_idx)
4246 || ipa_get_param_load_dereferenced (old_root_info, i));
4247 ipa_set_param_load_dereferenced (new_root_info, src_idx, lderef);
4250 if (c == 0 && !lderef && new_root_info->ipcp_orig_node)
4252 struct cgraph_node *n;
4253 struct ipa_ref *ref;
4254 tree t = new_root_info->known_csts[src_idx];
4256 if (t && TREE_CODE (t) == ADDR_EXPR
4257 && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
4258 && (n = cgraph_node::get (TREE_OPERAND (t, 0)))
4259 && (ref = new_root->find_reference (n, NULL, 0,
4260 IPA_REF_ADDR)))
4262 if (dump_file)
4263 fprintf (dump_file, "ipa-prop: Removing cloning-created "
4264 "reference from %s to %s.\n",
4265 new_root->dump_name (),
4266 n->dump_name ());
4267 ref->remove_reference ();
4271 else if (jf->type == IPA_JF_CONST
4272 && (rdesc = jfunc_rdesc_usable (jf)))
4274 int d = ipa_get_controlled_uses (old_root_info, i);
4275 int c = rdesc->refcount;
4276 tree cst = ipa_get_jf_constant (jf);
4277 rdesc->refcount = combine_controlled_uses_counters (c, d);
4278 if (rdesc->refcount != IPA_UNDESCRIBED_USE
4279 && ipa_get_param_load_dereferenced (old_root_info, i)
4280 && TREE_CODE (cst) == ADDR_EXPR
4281 && VAR_P (TREE_OPERAND (cst, 0)))
4283 symtab_node *n = symtab_node::get (TREE_OPERAND (cst, 0));
4284 new_root->create_reference (n, IPA_REF_LOAD, NULL);
4285 if (dump_file)
4286 fprintf (dump_file, "ipa-prop: Address IPA constant will reach "
4287 "a load so adding LOAD reference from %s to %s.\n",
4288 new_root->dump_name (), n->dump_name ());
4290 if (rdesc->refcount == 0)
4292 gcc_checking_assert (TREE_CODE (cst) == ADDR_EXPR
4293 && ((TREE_CODE (TREE_OPERAND (cst, 0))
4294 == FUNCTION_DECL)
4295 || VAR_P (TREE_OPERAND (cst, 0))));
4297 symtab_node *n = symtab_node::get (TREE_OPERAND (cst, 0));
4298 if (n)
4300 remove_described_reference (n, rdesc);
4301 cgraph_node *clone = cs->caller;
4302 while (clone->inlined_to
4303 && clone->ipcp_clone
4304 && clone != rdesc->cs->caller)
4306 struct ipa_ref *ref;
4307 ref = clone->find_reference (n, NULL, 0, IPA_REF_ADDR);
4308 if (ref)
4310 if (dump_file)
4311 fprintf (dump_file, "ipa-prop: Removing "
4312 "cloning-created reference "
4313 "from %s to %s.\n",
4314 clone->dump_name (),
4315 n->dump_name ());
4316 ref->remove_reference ();
4318 clone = clone->callers->caller;
4325 for (i = ipa_get_param_count (old_root_info);
4326 i < ipa_get_cs_argument_count (args);
4327 i++)
4329 struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
4331 if (jf->type == IPA_JF_CONST)
4333 struct ipa_cst_ref_desc *rdesc = jfunc_rdesc_usable (jf);
4334 if (rdesc)
4335 rdesc->refcount = IPA_UNDESCRIBED_USE;
4337 else if (jf->type == IPA_JF_PASS_THROUGH)
4338 ipa_set_controlled_uses (new_root_info,
4339 jf->value.pass_through.formal_id,
4340 IPA_UNDESCRIBED_USE);
4344 /* Update jump functions and call note functions on inlining the call site CS.
4345 CS is expected to lead to a node already cloned by
4346 cgraph_clone_inline_nodes. Newly discovered indirect edges will be added to
4347 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were +
4348 created. */
4350 bool
4351 ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
4352 vec<cgraph_edge *> *new_edges)
4354 bool changed;
4355 /* Do nothing if the preparation phase has not been carried out yet
4356 (i.e. during early inlining). */
4357 if (!ipa_node_params_sum)
4358 return false;
4359 gcc_assert (ipa_edge_args_sum);
4361 propagate_controlled_uses (cs);
4362 changed = propagate_info_to_inlined_callees (cs, cs->callee, new_edges);
4363 ipa_node_params_sum->remove (cs->callee);
4365 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
4366 if (args)
4368 bool ok = true;
4369 if (args->jump_functions)
4371 struct ipa_jump_func *jf;
4372 int i;
4373 FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
4374 if (jf->type == IPA_JF_CONST
4375 && ipa_get_jf_constant_rdesc (jf))
4377 ok = false;
4378 break;
4381 if (ok)
4382 ipa_edge_args_sum->remove (cs);
4384 if (ipcp_transformation_sum)
4385 ipcp_transformation_sum->remove (cs->callee);
4387 return changed;
4390 /* Ensure that array of edge arguments infos is big enough to accommodate a
4391 structure for all edges and reallocates it if not. Also, allocate
4392 associated hash tables is they do not already exist. */
4394 void
4395 ipa_check_create_edge_args (void)
4397 if (!ipa_edge_args_sum)
4398 ipa_edge_args_sum
4399 = (new (ggc_alloc_no_dtor<ipa_edge_args_sum_t> ())
4400 ipa_edge_args_sum_t (symtab, true));
4401 if (!ipa_vr_hash_table)
4402 ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
4405 /* Free all ipa_edge structures. */
4407 void
4408 ipa_free_all_edge_args (void)
4410 if (!ipa_edge_args_sum)
4411 return;
4413 ggc_delete (ipa_edge_args_sum);
4414 ipa_edge_args_sum = NULL;
4417 /* Free all ipa_node_params structures. */
4419 void
4420 ipa_free_all_node_params (void)
4422 if (ipa_node_params_sum)
4423 ggc_delete (ipa_node_params_sum);
4424 ipa_node_params_sum = NULL;
4427 /* Initialize IPA CP transformation summary and also allocate any necessary hash
4428 tables if they do not already exist. */
4430 void
4431 ipcp_transformation_initialize (void)
4433 if (!ipa_vr_hash_table)
4434 ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
4435 if (ipcp_transformation_sum == NULL)
4437 ipcp_transformation_sum = ipcp_transformation_t::create_ggc (symtab);
4438 ipcp_transformation_sum->disable_insertion_hook ();
4442 /* Release the IPA CP transformation summary. */
4444 void
4445 ipcp_free_transformation_sum (void)
4447 if (!ipcp_transformation_sum)
4448 return;
4450 ipcp_transformation_sum->~function_summary<ipcp_transformation *> ();
4451 ggc_free (ipcp_transformation_sum);
4452 ipcp_transformation_sum = NULL;
4455 /* Set the aggregate replacements of NODE to be AGGVALS. */
4457 void
4458 ipa_set_node_agg_value_chain (struct cgraph_node *node,
4459 vec<ipa_argagg_value, va_gc> *aggs)
4461 ipcp_transformation_initialize ();
4462 ipcp_transformation *s = ipcp_transformation_sum->get_create (node);
4463 s->m_agg_values = aggs;
4466 /* Hook that is called by cgraph.cc when an edge is removed. Adjust reference
4467 count data structures accordingly. */
4469 void
4470 ipa_edge_args_sum_t::remove (cgraph_edge *cs, ipa_edge_args *args)
4472 if (args->jump_functions)
4474 struct ipa_jump_func *jf;
4475 int i;
4476 FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
4478 struct ipa_cst_ref_desc *rdesc;
4479 try_decrement_rdesc_refcount (jf);
4480 if (jf->type == IPA_JF_CONST
4481 && (rdesc = ipa_get_jf_constant_rdesc (jf))
4482 && rdesc->cs == cs)
4483 rdesc->cs = NULL;
4488 /* Method invoked when an edge is duplicated. Copy ipa_edge_args and adjust
4489 reference count data strucutres accordingly. */
4491 void
4492 ipa_edge_args_sum_t::duplicate (cgraph_edge *src, cgraph_edge *dst,
4493 ipa_edge_args *old_args, ipa_edge_args *new_args)
4495 unsigned int i;
4497 new_args->jump_functions = vec_safe_copy (old_args->jump_functions);
4498 if (old_args->polymorphic_call_contexts)
4499 new_args->polymorphic_call_contexts
4500 = vec_safe_copy (old_args->polymorphic_call_contexts);
4502 for (i = 0; i < vec_safe_length (old_args->jump_functions); i++)
4504 struct ipa_jump_func *src_jf = ipa_get_ith_jump_func (old_args, i);
4505 struct ipa_jump_func *dst_jf = ipa_get_ith_jump_func (new_args, i);
4507 dst_jf->agg.items = vec_safe_copy (dst_jf->agg.items);
4509 if (src_jf->type == IPA_JF_CONST)
4511 struct ipa_cst_ref_desc *src_rdesc = jfunc_rdesc_usable (src_jf);
4513 if (!src_rdesc)
4514 dst_jf->value.constant.rdesc = NULL;
4515 else if (src->caller == dst->caller)
4517 /* Creation of a speculative edge. If the source edge is the one
4518 grabbing a reference, we must create a new (duplicate)
4519 reference description. Otherwise they refer to the same
4520 description corresponding to a reference taken in a function
4521 src->caller is inlined to. In that case we just must
4522 increment the refcount. */
4523 if (src_rdesc->cs == src)
4525 symtab_node *n = symtab_node_for_jfunc (src_jf);
4526 gcc_checking_assert (n);
4527 ipa_ref *ref
4528 = src->caller->find_reference (n, src->call_stmt,
4529 src->lto_stmt_uid,
4530 IPA_REF_ADDR);
4531 gcc_checking_assert (ref);
4532 dst->caller->clone_reference (ref, ref->stmt);
4534 ipa_cst_ref_desc *dst_rdesc = ipa_refdesc_pool.allocate ();
4535 dst_rdesc->cs = dst;
4536 dst_rdesc->refcount = src_rdesc->refcount;
4537 dst_rdesc->next_duplicate = NULL;
4538 dst_jf->value.constant.rdesc = dst_rdesc;
4540 else
4542 src_rdesc->refcount++;
4543 dst_jf->value.constant.rdesc = src_rdesc;
4546 else if (src_rdesc->cs == src)
4548 struct ipa_cst_ref_desc *dst_rdesc = ipa_refdesc_pool.allocate ();
4549 dst_rdesc->cs = dst;
4550 dst_rdesc->refcount = src_rdesc->refcount;
4551 dst_rdesc->next_duplicate = src_rdesc->next_duplicate;
4552 src_rdesc->next_duplicate = dst_rdesc;
4553 dst_jf->value.constant.rdesc = dst_rdesc;
4555 else
4557 struct ipa_cst_ref_desc *dst_rdesc;
4558 /* This can happen during inlining, when a JFUNC can refer to a
4559 reference taken in a function up in the tree of inline clones.
4560 We need to find the duplicate that refers to our tree of
4561 inline clones. */
4563 gcc_assert (dst->caller->inlined_to);
4564 for (dst_rdesc = src_rdesc->next_duplicate;
4565 dst_rdesc;
4566 dst_rdesc = dst_rdesc->next_duplicate)
4568 struct cgraph_node *top;
4569 top = dst_rdesc->cs->caller->inlined_to
4570 ? dst_rdesc->cs->caller->inlined_to
4571 : dst_rdesc->cs->caller;
4572 if (dst->caller->inlined_to == top)
4573 break;
4575 gcc_assert (dst_rdesc);
4576 dst_jf->value.constant.rdesc = dst_rdesc;
4579 else if (dst_jf->type == IPA_JF_PASS_THROUGH
4580 && src->caller == dst->caller)
4582 struct cgraph_node *inline_root = dst->caller->inlined_to
4583 ? dst->caller->inlined_to : dst->caller;
4584 ipa_node_params *root_info = ipa_node_params_sum->get (inline_root);
4585 int idx = ipa_get_jf_pass_through_formal_id (dst_jf);
4587 int c = ipa_get_controlled_uses (root_info, idx);
4588 if (c != IPA_UNDESCRIBED_USE)
4590 c++;
4591 ipa_set_controlled_uses (root_info, idx, c);
4597 /* Analyze newly added function into callgraph. */
4599 static void
4600 ipa_add_new_function (cgraph_node *node, void *data ATTRIBUTE_UNUSED)
4602 if (node->has_gimple_body_p ())
4603 ipa_analyze_node (node);
4606 /* Hook that is called by summary when a node is duplicated. */
4608 void
4609 ipa_node_params_t::duplicate(cgraph_node *, cgraph_node *,
4610 ipa_node_params *old_info,
4611 ipa_node_params *new_info)
4613 new_info->descriptors = vec_safe_copy (old_info->descriptors);
4614 gcc_assert (new_info->lattices.is_empty ());
4615 new_info->ipcp_orig_node = old_info->ipcp_orig_node;
4616 new_info->known_csts = old_info->known_csts.copy ();
4617 new_info->known_contexts = old_info->known_contexts.copy ();
4619 new_info->analysis_done = old_info->analysis_done;
4620 new_info->node_enqueued = old_info->node_enqueued;
4621 new_info->versionable = old_info->versionable;
4624 /* Duplication of ipcp transformation summaries. */
4626 void
4627 ipcp_transformation_t::duplicate(cgraph_node *, cgraph_node *dst,
4628 ipcp_transformation *src_trans,
4629 ipcp_transformation *dst_trans)
4631 /* Avoid redundant work of duplicating vectors we will never use. */
4632 if (dst->inlined_to)
4633 return;
4634 dst_trans->m_agg_values = vec_safe_copy (src_trans->m_agg_values);
4635 dst_trans->m_vr = vec_safe_copy (src_trans->m_vr);
4638 /* Register our cgraph hooks if they are not already there. */
4640 void
4641 ipa_register_cgraph_hooks (void)
4643 ipa_check_create_node_params ();
4644 ipa_check_create_edge_args ();
4646 function_insertion_hook_holder =
4647 symtab->add_cgraph_insertion_hook (&ipa_add_new_function, NULL);
4650 /* Unregister our cgraph hooks if they are not already there. */
4652 static void
4653 ipa_unregister_cgraph_hooks (void)
4655 if (function_insertion_hook_holder)
4656 symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
4657 function_insertion_hook_holder = NULL;
4660 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
4661 longer needed after ipa-cp. */
4663 void
4664 ipa_free_all_structures_after_ipa_cp (void)
4666 if (!optimize && !in_lto_p)
4668 ipa_free_all_edge_args ();
4669 ipa_free_all_node_params ();
4670 ipcp_sources_pool.release ();
4671 ipcp_cst_values_pool.release ();
4672 ipcp_poly_ctx_values_pool.release ();
4673 ipcp_agg_lattice_pool.release ();
4674 ipa_unregister_cgraph_hooks ();
4675 ipa_refdesc_pool.release ();
4679 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
4680 longer needed after indirect inlining. */
4682 void
4683 ipa_free_all_structures_after_iinln (void)
4685 ipa_free_all_edge_args ();
4686 ipa_free_all_node_params ();
4687 ipa_unregister_cgraph_hooks ();
4688 ipcp_sources_pool.release ();
4689 ipcp_cst_values_pool.release ();
4690 ipcp_poly_ctx_values_pool.release ();
4691 ipcp_agg_lattice_pool.release ();
4692 ipa_refdesc_pool.release ();
4695 /* Print ipa_tree_map data structures of all functions in the
4696 callgraph to F. */
4698 void
4699 ipa_print_node_params (FILE *f, struct cgraph_node *node)
4701 int i, count;
4702 class ipa_node_params *info;
4704 if (!node->definition)
4705 return;
4706 info = ipa_node_params_sum->get (node);
4707 fprintf (f, " function %s parameter descriptors:\n", node->dump_name ());
4708 if (!info)
4710 fprintf (f, " no params return\n");
4711 return;
4713 count = ipa_get_param_count (info);
4714 for (i = 0; i < count; i++)
4716 int c;
4718 fprintf (f, " ");
4719 ipa_dump_param (f, info, i);
4720 if (ipa_is_param_used (info, i))
4721 fprintf (f, " used");
4722 if (ipa_is_param_used_by_ipa_predicates (info, i))
4723 fprintf (f, " used_by_ipa_predicates");
4724 if (ipa_is_param_used_by_indirect_call (info, i))
4725 fprintf (f, " used_by_indirect_call");
4726 if (ipa_is_param_used_by_polymorphic_call (info, i))
4727 fprintf (f, " used_by_polymorphic_call");
4728 c = ipa_get_controlled_uses (info, i);
4729 if (c == IPA_UNDESCRIBED_USE)
4730 fprintf (f, " undescribed_use");
4731 else
4732 fprintf (f, " controlled_uses=%i %s", c,
4733 ipa_get_param_load_dereferenced (info, i)
4734 ? "(load_dereferenced)" : "");
4735 fprintf (f, "\n");
4739 /* Print ipa_tree_map data structures of all functions in the
4740 callgraph to F. */
4742 void
4743 ipa_print_all_params (FILE * f)
4745 struct cgraph_node *node;
4747 fprintf (f, "\nFunction parameters:\n");
4748 FOR_EACH_FUNCTION (node)
4749 ipa_print_node_params (f, node);
4752 /* Stream out jump function JUMP_FUNC to OB. */
4754 static void
4755 ipa_write_jump_function (struct output_block *ob,
4756 struct ipa_jump_func *jump_func)
4758 struct ipa_agg_jf_item *item;
4759 struct bitpack_d bp;
4760 int i, count;
4761 int flag = 0;
4763 /* ADDR_EXPRs are very comon IP invariants; save some streamer data
4764 as well as WPA memory by handling them specially. */
4765 if (jump_func->type == IPA_JF_CONST
4766 && TREE_CODE (jump_func->value.constant.value) == ADDR_EXPR)
4767 flag = 1;
4769 streamer_write_uhwi (ob, jump_func->type * 2 + flag);
4770 switch (jump_func->type)
4772 case IPA_JF_UNKNOWN:
4773 break;
4774 case IPA_JF_CONST:
4775 gcc_assert (
4776 EXPR_LOCATION (jump_func->value.constant.value) == UNKNOWN_LOCATION);
4777 stream_write_tree (ob,
4778 flag
4779 ? TREE_OPERAND (jump_func->value.constant.value, 0)
4780 : jump_func->value.constant.value, true);
4781 break;
4782 case IPA_JF_PASS_THROUGH:
4783 streamer_write_uhwi (ob, jump_func->value.pass_through.operation);
4784 if (jump_func->value.pass_through.operation == NOP_EXPR)
4786 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4787 bp = bitpack_create (ob->main_stream);
4788 bp_pack_value (&bp, jump_func->value.pass_through.agg_preserved, 1);
4789 gcc_assert (!jump_func->value.pass_through.refdesc_decremented);
4790 streamer_write_bitpack (&bp);
4792 else if (TREE_CODE_CLASS (jump_func->value.pass_through.operation)
4793 == tcc_unary)
4794 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4795 else
4797 stream_write_tree (ob, jump_func->value.pass_through.operand, true);
4798 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4800 break;
4801 case IPA_JF_ANCESTOR:
4802 streamer_write_uhwi (ob, jump_func->value.ancestor.offset);
4803 streamer_write_uhwi (ob, jump_func->value.ancestor.formal_id);
4804 bp = bitpack_create (ob->main_stream);
4805 bp_pack_value (&bp, jump_func->value.ancestor.agg_preserved, 1);
4806 bp_pack_value (&bp, jump_func->value.ancestor.keep_null, 1);
4807 streamer_write_bitpack (&bp);
4808 break;
4809 default:
4810 fatal_error (UNKNOWN_LOCATION, "invalid jump function in LTO stream");
4813 count = vec_safe_length (jump_func->agg.items);
4814 streamer_write_uhwi (ob, count);
4815 if (count)
4817 bp = bitpack_create (ob->main_stream);
4818 bp_pack_value (&bp, jump_func->agg.by_ref, 1);
4819 streamer_write_bitpack (&bp);
4822 FOR_EACH_VEC_SAFE_ELT (jump_func->agg.items, i, item)
4824 stream_write_tree (ob, item->type, true);
4825 streamer_write_uhwi (ob, item->offset);
4826 streamer_write_uhwi (ob, item->jftype);
4827 switch (item->jftype)
4829 case IPA_JF_UNKNOWN:
4830 break;
4831 case IPA_JF_CONST:
4832 stream_write_tree (ob, item->value.constant, true);
4833 break;
4834 case IPA_JF_PASS_THROUGH:
4835 case IPA_JF_LOAD_AGG:
4836 streamer_write_uhwi (ob, item->value.pass_through.operation);
4837 streamer_write_uhwi (ob, item->value.pass_through.formal_id);
4838 if (TREE_CODE_CLASS (item->value.pass_through.operation)
4839 != tcc_unary)
4840 stream_write_tree (ob, item->value.pass_through.operand, true);
4841 if (item->jftype == IPA_JF_LOAD_AGG)
4843 stream_write_tree (ob, item->value.load_agg.type, true);
4844 streamer_write_uhwi (ob, item->value.load_agg.offset);
4845 bp = bitpack_create (ob->main_stream);
4846 bp_pack_value (&bp, item->value.load_agg.by_ref, 1);
4847 streamer_write_bitpack (&bp);
4849 break;
4850 default:
4851 fatal_error (UNKNOWN_LOCATION,
4852 "invalid jump function in LTO stream");
4856 bp = bitpack_create (ob->main_stream);
4857 if (jump_func->m_vr)
4858 jump_func->m_vr->streamer_write (ob);
4859 else
4861 bp_pack_value (&bp, false, 1);
4862 streamer_write_bitpack (&bp);
4866 /* Read in jump function JUMP_FUNC from IB. */
4868 static void
4869 ipa_read_jump_function (class lto_input_block *ib,
4870 struct ipa_jump_func *jump_func,
4871 struct cgraph_edge *cs,
4872 class data_in *data_in,
4873 bool prevails)
4875 enum jump_func_type jftype;
4876 enum tree_code operation;
4877 int i, count;
4878 int val = streamer_read_uhwi (ib);
4879 bool flag = val & 1;
4881 jftype = (enum jump_func_type) (val / 2);
4882 switch (jftype)
4884 case IPA_JF_UNKNOWN:
4885 ipa_set_jf_unknown (jump_func);
4886 break;
4887 case IPA_JF_CONST:
4889 tree t = stream_read_tree (ib, data_in);
4890 if (flag && prevails)
4891 t = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
4892 ipa_set_jf_constant (jump_func, t, cs);
4894 break;
4895 case IPA_JF_PASS_THROUGH:
4896 operation = (enum tree_code) streamer_read_uhwi (ib);
4897 if (operation == NOP_EXPR)
4899 int formal_id = streamer_read_uhwi (ib);
4900 struct bitpack_d bp = streamer_read_bitpack (ib);
4901 bool agg_preserved = bp_unpack_value (&bp, 1);
4902 ipa_set_jf_simple_pass_through (jump_func, formal_id, agg_preserved);
4904 else if (TREE_CODE_CLASS (operation) == tcc_unary)
4906 int formal_id = streamer_read_uhwi (ib);
4907 ipa_set_jf_unary_pass_through (jump_func, formal_id, operation);
4909 else
4911 tree operand = stream_read_tree (ib, data_in);
4912 int formal_id = streamer_read_uhwi (ib);
4913 ipa_set_jf_arith_pass_through (jump_func, formal_id, operand,
4914 operation);
4916 break;
4917 case IPA_JF_ANCESTOR:
4919 HOST_WIDE_INT offset = streamer_read_uhwi (ib);
4920 int formal_id = streamer_read_uhwi (ib);
4921 struct bitpack_d bp = streamer_read_bitpack (ib);
4922 bool agg_preserved = bp_unpack_value (&bp, 1);
4923 bool keep_null = bp_unpack_value (&bp, 1);
4924 ipa_set_ancestor_jf (jump_func, offset, formal_id, agg_preserved,
4925 keep_null);
4926 break;
4928 default:
4929 fatal_error (UNKNOWN_LOCATION, "invalid jump function in LTO stream");
4932 count = streamer_read_uhwi (ib);
4933 if (prevails)
4935 jump_func->agg.items = NULL;
4936 vec_safe_reserve (jump_func->agg.items, count, true);
4938 if (count)
4940 struct bitpack_d bp = streamer_read_bitpack (ib);
4941 jump_func->agg.by_ref = bp_unpack_value (&bp, 1);
4943 for (i = 0; i < count; i++)
4945 struct ipa_agg_jf_item item;
4946 item.type = stream_read_tree (ib, data_in);
4947 item.offset = streamer_read_uhwi (ib);
4948 item.jftype = (enum jump_func_type) streamer_read_uhwi (ib);
4950 switch (item.jftype)
4952 case IPA_JF_UNKNOWN:
4953 break;
4954 case IPA_JF_CONST:
4955 item.value.constant = stream_read_tree (ib, data_in);
4956 break;
4957 case IPA_JF_PASS_THROUGH:
4958 case IPA_JF_LOAD_AGG:
4959 operation = (enum tree_code) streamer_read_uhwi (ib);
4960 item.value.pass_through.operation = operation;
4961 item.value.pass_through.formal_id = streamer_read_uhwi (ib);
4962 if (TREE_CODE_CLASS (operation) == tcc_unary)
4963 item.value.pass_through.operand = NULL_TREE;
4964 else
4965 item.value.pass_through.operand = stream_read_tree (ib, data_in);
4966 if (item.jftype == IPA_JF_LOAD_AGG)
4968 struct bitpack_d bp;
4969 item.value.load_agg.type = stream_read_tree (ib, data_in);
4970 item.value.load_agg.offset = streamer_read_uhwi (ib);
4971 bp = streamer_read_bitpack (ib);
4972 item.value.load_agg.by_ref = bp_unpack_value (&bp, 1);
4974 break;
4975 default:
4976 fatal_error (UNKNOWN_LOCATION,
4977 "invalid jump function in LTO stream");
4979 if (prevails)
4980 jump_func->agg.items->quick_push (item);
4983 ipa_vr vr;
4984 vr.streamer_read (ib, data_in);
4985 if (vr.known_p ())
4987 if (prevails)
4988 ipa_set_jfunc_vr (jump_func, vr);
4990 else
4991 jump_func->m_vr = NULL;
4994 /* Stream out parts of cgraph_indirect_call_info corresponding to CS that are
4995 relevant to indirect inlining to OB. */
4997 static void
4998 ipa_write_indirect_edge_info (struct output_block *ob,
4999 struct cgraph_edge *cs)
5001 class cgraph_indirect_call_info *ii = cs->indirect_info;
5002 struct bitpack_d bp;
5004 streamer_write_hwi (ob, ii->param_index);
5005 bp = bitpack_create (ob->main_stream);
5006 bp_pack_value (&bp, ii->polymorphic, 1);
5007 bp_pack_value (&bp, ii->agg_contents, 1);
5008 bp_pack_value (&bp, ii->member_ptr, 1);
5009 bp_pack_value (&bp, ii->by_ref, 1);
5010 bp_pack_value (&bp, ii->guaranteed_unmodified, 1);
5011 bp_pack_value (&bp, ii->vptr_changed, 1);
5012 streamer_write_bitpack (&bp);
5013 if (ii->agg_contents || ii->polymorphic)
5014 streamer_write_hwi (ob, ii->offset);
5015 else
5016 gcc_assert (ii->offset == 0);
5018 if (ii->polymorphic)
5020 streamer_write_hwi (ob, ii->otr_token);
5021 stream_write_tree (ob, ii->otr_type, true);
5022 ii->context.stream_out (ob);
5026 /* Read in parts of cgraph_indirect_call_info corresponding to CS that are
5027 relevant to indirect inlining from IB. */
5029 static void
5030 ipa_read_indirect_edge_info (class lto_input_block *ib,
5031 class data_in *data_in,
5032 struct cgraph_edge *cs,
5033 class ipa_node_params *info)
5035 class cgraph_indirect_call_info *ii = cs->indirect_info;
5036 struct bitpack_d bp;
5038 ii->param_index = (int) streamer_read_hwi (ib);
5039 bp = streamer_read_bitpack (ib);
5040 ii->polymorphic = bp_unpack_value (&bp, 1);
5041 ii->agg_contents = bp_unpack_value (&bp, 1);
5042 ii->member_ptr = bp_unpack_value (&bp, 1);
5043 ii->by_ref = bp_unpack_value (&bp, 1);
5044 ii->guaranteed_unmodified = bp_unpack_value (&bp, 1);
5045 ii->vptr_changed = bp_unpack_value (&bp, 1);
5046 if (ii->agg_contents || ii->polymorphic)
5047 ii->offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
5048 else
5049 ii->offset = 0;
5050 if (ii->polymorphic)
5052 ii->otr_token = (HOST_WIDE_INT) streamer_read_hwi (ib);
5053 ii->otr_type = stream_read_tree (ib, data_in);
5054 ii->context.stream_in (ib, data_in);
5056 if (info && ii->param_index >= 0)
5058 if (ii->polymorphic)
5059 ipa_set_param_used_by_polymorphic_call (info,
5060 ii->param_index , true);
5061 ipa_set_param_used_by_indirect_call (info,
5062 ii->param_index, true);
5066 /* Stream out NODE info to OB. */
5068 static void
5069 ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
5071 int node_ref;
5072 lto_symtab_encoder_t encoder;
5073 ipa_node_params *info = ipa_node_params_sum->get (node);
5074 int j;
5075 struct cgraph_edge *e;
5076 struct bitpack_d bp;
5078 encoder = ob->decl_state->symtab_node_encoder;
5079 node_ref = lto_symtab_encoder_encode (encoder, node);
5080 streamer_write_uhwi (ob, node_ref);
5082 streamer_write_uhwi (ob, ipa_get_param_count (info));
5083 for (j = 0; j < ipa_get_param_count (info); j++)
5084 streamer_write_uhwi (ob, ipa_get_param_move_cost (info, j));
5085 bp = bitpack_create (ob->main_stream);
5086 gcc_assert (info->analysis_done
5087 || ipa_get_param_count (info) == 0);
5088 gcc_assert (!info->node_enqueued);
5089 gcc_assert (!info->ipcp_orig_node);
5090 for (j = 0; j < ipa_get_param_count (info); j++)
5092 /* TODO: We could just not stream the bit in the undescribed case. */
5093 bool d = (ipa_get_controlled_uses (info, j) != IPA_UNDESCRIBED_USE)
5094 ? ipa_get_param_load_dereferenced (info, j) : true;
5095 bp_pack_value (&bp, d, 1);
5096 bp_pack_value (&bp, ipa_is_param_used (info, j), 1);
5098 streamer_write_bitpack (&bp);
5099 for (j = 0; j < ipa_get_param_count (info); j++)
5101 streamer_write_hwi (ob, ipa_get_controlled_uses (info, j));
5102 stream_write_tree (ob, ipa_get_type (info, j), true);
5104 for (e = node->callees; e; e = e->next_callee)
5106 ipa_edge_args *args = ipa_edge_args_sum->get (e);
5108 if (!args)
5110 streamer_write_uhwi (ob, 0);
5111 continue;
5114 streamer_write_uhwi (ob,
5115 ipa_get_cs_argument_count (args) * 2
5116 + (args->polymorphic_call_contexts != NULL));
5117 for (j = 0; j < ipa_get_cs_argument_count (args); j++)
5119 ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
5120 if (args->polymorphic_call_contexts != NULL)
5121 ipa_get_ith_polymorhic_call_context (args, j)->stream_out (ob);
5124 for (e = node->indirect_calls; e; e = e->next_callee)
5126 ipa_edge_args *args = ipa_edge_args_sum->get (e);
5127 if (!args)
5128 streamer_write_uhwi (ob, 0);
5129 else
5131 streamer_write_uhwi (ob,
5132 ipa_get_cs_argument_count (args) * 2
5133 + (args->polymorphic_call_contexts != NULL));
5134 for (j = 0; j < ipa_get_cs_argument_count (args); j++)
5136 ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
5137 if (args->polymorphic_call_contexts != NULL)
5138 ipa_get_ith_polymorhic_call_context (args, j)->stream_out (ob);
5141 ipa_write_indirect_edge_info (ob, e);
5145 /* Stream in edge E from IB. */
5147 static void
5148 ipa_read_edge_info (class lto_input_block *ib,
5149 class data_in *data_in,
5150 struct cgraph_edge *e, bool prevails)
5152 int count = streamer_read_uhwi (ib);
5153 bool contexts_computed = count & 1;
5155 count /= 2;
5156 if (!count)
5157 return;
5158 if (prevails
5159 && (e->possibly_call_in_translation_unit_p ()
5160 /* Also stream in jump functions to builtins in hope that they
5161 will get fnspecs. */
5162 || fndecl_built_in_p (e->callee->decl, BUILT_IN_NORMAL)))
5164 ipa_edge_args *args = ipa_edge_args_sum->get_create (e);
5165 vec_safe_grow_cleared (args->jump_functions, count, true);
5166 if (contexts_computed)
5167 vec_safe_grow_cleared (args->polymorphic_call_contexts, count, true);
5168 for (int k = 0; k < count; k++)
5170 ipa_read_jump_function (ib, ipa_get_ith_jump_func (args, k), e,
5171 data_in, prevails);
5172 if (contexts_computed)
5173 ipa_get_ith_polymorhic_call_context (args, k)->stream_in
5174 (ib, data_in);
5177 else
5179 for (int k = 0; k < count; k++)
5181 struct ipa_jump_func dummy;
5182 ipa_read_jump_function (ib, &dummy, e,
5183 data_in, prevails);
5184 if (contexts_computed)
5186 class ipa_polymorphic_call_context ctx;
5187 ctx.stream_in (ib, data_in);
5193 /* Stream in NODE info from IB. */
5195 static void
5196 ipa_read_node_info (class lto_input_block *ib, struct cgraph_node *node,
5197 class data_in *data_in)
5199 int k;
5200 struct cgraph_edge *e;
5201 struct bitpack_d bp;
5202 bool prevails = node->prevailing_p ();
5203 ipa_node_params *info
5204 = prevails ? ipa_node_params_sum->get_create (node) : NULL;
5206 int param_count = streamer_read_uhwi (ib);
5207 if (prevails)
5209 ipa_alloc_node_params (node, param_count);
5210 for (k = 0; k < param_count; k++)
5211 (*info->descriptors)[k].move_cost = streamer_read_uhwi (ib);
5212 if (ipa_get_param_count (info) != 0)
5213 info->analysis_done = true;
5214 info->node_enqueued = false;
5216 else
5217 for (k = 0; k < param_count; k++)
5218 streamer_read_uhwi (ib);
5220 bp = streamer_read_bitpack (ib);
5221 for (k = 0; k < param_count; k++)
5223 bool load_dereferenced = bp_unpack_value (&bp, 1);
5224 bool used = bp_unpack_value (&bp, 1);
5226 if (prevails)
5228 ipa_set_param_load_dereferenced (info, k, load_dereferenced);
5229 ipa_set_param_used (info, k, used);
5232 for (k = 0; k < param_count; k++)
5234 int nuses = streamer_read_hwi (ib);
5235 tree type = stream_read_tree (ib, data_in);
5237 if (prevails)
5239 ipa_set_controlled_uses (info, k, nuses);
5240 (*info->descriptors)[k].decl_or_type = type;
5243 for (e = node->callees; e; e = e->next_callee)
5244 ipa_read_edge_info (ib, data_in, e, prevails);
5245 for (e = node->indirect_calls; e; e = e->next_callee)
5247 ipa_read_edge_info (ib, data_in, e, prevails);
5248 ipa_read_indirect_edge_info (ib, data_in, e, info);
5252 /* Write jump functions for nodes in SET. */
5254 void
5255 ipa_prop_write_jump_functions (void)
5257 struct output_block *ob;
5258 unsigned int count = 0;
5259 lto_symtab_encoder_iterator lsei;
5260 lto_symtab_encoder_t encoder;
5262 if (!ipa_node_params_sum || !ipa_edge_args_sum)
5263 return;
5265 ob = create_output_block (LTO_section_jump_functions);
5266 encoder = ob->decl_state->symtab_node_encoder;
5267 ob->symbol = NULL;
5268 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
5269 lsei_next_function_in_partition (&lsei))
5271 cgraph_node *node = lsei_cgraph_node (lsei);
5272 if (node->has_gimple_body_p ()
5273 && ipa_node_params_sum->get (node) != NULL)
5274 count++;
5277 streamer_write_uhwi (ob, count);
5279 /* Process all of the functions. */
5280 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
5281 lsei_next_function_in_partition (&lsei))
5283 cgraph_node *node = lsei_cgraph_node (lsei);
5284 if (node->has_gimple_body_p ()
5285 && ipa_node_params_sum->get (node) != NULL)
5286 ipa_write_node_info (ob, node);
5288 streamer_write_char_stream (ob->main_stream, 0);
5289 produce_asm (ob, NULL);
5290 destroy_output_block (ob);
5293 /* Read section in file FILE_DATA of length LEN with data DATA. */
5295 static void
5296 ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
5297 size_t len)
5299 const struct lto_function_header *header =
5300 (const struct lto_function_header *) data;
5301 const int cfg_offset = sizeof (struct lto_function_header);
5302 const int main_offset = cfg_offset + header->cfg_size;
5303 const int string_offset = main_offset + header->main_size;
5304 class data_in *data_in;
5305 unsigned int i;
5306 unsigned int count;
5308 lto_input_block ib_main ((const char *) data + main_offset,
5309 header->main_size, file_data);
5311 data_in =
5312 lto_data_in_create (file_data, (const char *) data + string_offset,
5313 header->string_size, vNULL);
5314 count = streamer_read_uhwi (&ib_main);
5316 for (i = 0; i < count; i++)
5318 unsigned int index;
5319 struct cgraph_node *node;
5320 lto_symtab_encoder_t encoder;
5322 index = streamer_read_uhwi (&ib_main);
5323 encoder = file_data->symtab_node_encoder;
5324 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
5325 index));
5326 gcc_assert (node->definition);
5327 ipa_read_node_info (&ib_main, node, data_in);
5329 lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
5330 len);
5331 lto_data_in_delete (data_in);
5334 /* Read ipcp jump functions. */
5336 void
5337 ipa_prop_read_jump_functions (void)
5339 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
5340 struct lto_file_decl_data *file_data;
5341 unsigned int j = 0;
5343 ipa_check_create_node_params ();
5344 ipa_check_create_edge_args ();
5345 ipa_register_cgraph_hooks ();
5347 while ((file_data = file_data_vec[j++]))
5349 size_t len;
5350 const char *data
5351 = lto_get_summary_section_data (file_data, LTO_section_jump_functions,
5352 &len);
5353 if (data)
5354 ipa_prop_read_section (file_data, data, len);
5358 /* Return true if the IPA-CP transformation summary TS is non-NULL and contains
5359 useful info. */
5360 static bool
5361 useful_ipcp_transformation_info_p (ipcp_transformation *ts)
5363 if (!ts)
5364 return false;
5365 if (!vec_safe_is_empty (ts->m_agg_values)
5366 || !vec_safe_is_empty (ts->m_vr))
5367 return true;
5368 return false;
5371 /* Write into OB IPA-CP transfromation summary TS describing NODE. */
5373 void
5374 write_ipcp_transformation_info (output_block *ob, cgraph_node *node,
5375 ipcp_transformation *ts)
5377 lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
5378 int node_ref = lto_symtab_encoder_encode (encoder, node);
5379 streamer_write_uhwi (ob, node_ref);
5381 streamer_write_uhwi (ob, vec_safe_length (ts->m_agg_values));
5382 for (const ipa_argagg_value &av : ts->m_agg_values)
5384 struct bitpack_d bp;
5386 stream_write_tree (ob, av.value, true);
5387 streamer_write_uhwi (ob, av.unit_offset);
5388 streamer_write_uhwi (ob, av.index);
5390 bp = bitpack_create (ob->main_stream);
5391 bp_pack_value (&bp, av.by_ref, 1);
5392 bp_pack_value (&bp, av.killed, 1);
5393 streamer_write_bitpack (&bp);
5396 streamer_write_uhwi (ob, vec_safe_length (ts->m_vr));
5397 for (const ipa_vr &parm_vr : ts->m_vr)
5398 parm_vr.streamer_write (ob);
5401 /* Stream in the aggregate value replacement chain for NODE from IB. */
5403 static void
5404 read_ipcp_transformation_info (lto_input_block *ib, cgraph_node *node,
5405 data_in *data_in)
5407 unsigned int count, i;
5408 ipcp_transformation_initialize ();
5409 ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
5411 count = streamer_read_uhwi (ib);
5412 if (count > 0)
5414 vec_safe_grow_cleared (ts->m_agg_values, count, true);
5415 for (i = 0; i <count; i++)
5417 ipa_argagg_value *av = &(*ts->m_agg_values)[i];;
5419 av->value = stream_read_tree (ib, data_in);
5420 av->unit_offset = streamer_read_uhwi (ib);
5421 av->index = streamer_read_uhwi (ib);
5423 bitpack_d bp = streamer_read_bitpack (ib);
5424 av->by_ref = bp_unpack_value (&bp, 1);
5425 av->killed = bp_unpack_value (&bp, 1);
5429 count = streamer_read_uhwi (ib);
5430 if (count > 0)
5432 vec_safe_grow_cleared (ts->m_vr, count, true);
5433 for (i = 0; i < count; i++)
5435 ipa_vr *parm_vr;
5436 parm_vr = &(*ts->m_vr)[i];
5437 parm_vr->streamer_read (ib, data_in);
5442 /* Write all aggregate replacement for nodes in set. */
5444 void
5445 ipcp_write_transformation_summaries (void)
5447 struct output_block *ob;
5448 unsigned int count = 0;
5449 lto_symtab_encoder_t encoder;
5451 ob = create_output_block (LTO_section_ipcp_transform);
5452 encoder = ob->decl_state->symtab_node_encoder;
5453 ob->symbol = NULL;
5455 for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
5457 symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
5458 cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
5459 if (!cnode)
5460 continue;
5461 ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
5462 if (useful_ipcp_transformation_info_p (ts)
5463 && lto_symtab_encoder_encode_body_p (encoder, cnode))
5464 count++;
5467 streamer_write_uhwi (ob, count);
5469 for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
5471 symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
5472 cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
5473 if (!cnode)
5474 continue;
5475 ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
5476 if (useful_ipcp_transformation_info_p (ts)
5477 && lto_symtab_encoder_encode_body_p (encoder, cnode))
5478 write_ipcp_transformation_info (ob, cnode, ts);
5480 streamer_write_char_stream (ob->main_stream, 0);
5481 produce_asm (ob, NULL);
5482 destroy_output_block (ob);
5485 /* Read replacements section in file FILE_DATA of length LEN with data
5486 DATA. */
5488 static void
5489 read_replacements_section (struct lto_file_decl_data *file_data,
5490 const char *data,
5491 size_t len)
5493 const struct lto_function_header *header =
5494 (const struct lto_function_header *) data;
5495 const int cfg_offset = sizeof (struct lto_function_header);
5496 const int main_offset = cfg_offset + header->cfg_size;
5497 const int string_offset = main_offset + header->main_size;
5498 class data_in *data_in;
5499 unsigned int i;
5500 unsigned int count;
5502 lto_input_block ib_main ((const char *) data + main_offset,
5503 header->main_size, file_data);
5505 data_in = lto_data_in_create (file_data, (const char *) data + string_offset,
5506 header->string_size, vNULL);
5507 count = streamer_read_uhwi (&ib_main);
5509 for (i = 0; i < count; i++)
5511 unsigned int index;
5512 struct cgraph_node *node;
5513 lto_symtab_encoder_t encoder;
5515 index = streamer_read_uhwi (&ib_main);
5516 encoder = file_data->symtab_node_encoder;
5517 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
5518 index));
5519 read_ipcp_transformation_info (&ib_main, node, data_in);
5521 lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
5522 len);
5523 lto_data_in_delete (data_in);
5526 /* Read IPA-CP aggregate replacements. */
5528 void
5529 ipcp_read_transformation_summaries (void)
5531 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
5532 struct lto_file_decl_data *file_data;
5533 unsigned int j = 0;
5535 while ((file_data = file_data_vec[j++]))
5537 size_t len;
5538 const char *data
5539 = lto_get_summary_section_data (file_data, LTO_section_ipcp_transform,
5540 &len);
5541 if (data)
5542 read_replacements_section (file_data, data, len);
5546 /* Adjust the aggregate replacements in TS to reflect any parameter removals
5547 which might have already taken place. If after adjustments there are no
5548 aggregate replacements left, the m_agg_values will be set to NULL. In other
5549 cases, it may be shrunk. */
5551 static void
5552 adjust_agg_replacement_values (cgraph_node *node, ipcp_transformation *ts)
5554 clone_info *cinfo = clone_info::get (node);
5555 if (!cinfo || !cinfo->param_adjustments)
5556 return;
5558 auto_vec<int, 16> new_indices;
5559 cinfo->param_adjustments->get_updated_indices (&new_indices);
5560 bool removed_item = false;
5561 unsigned dst_index = 0;
5562 unsigned count = ts->m_agg_values->length ();
5563 for (unsigned i = 0; i < count; i++)
5565 ipa_argagg_value *v = &(*ts->m_agg_values)[i];
5566 gcc_checking_assert (v->index >= 0);
5568 int new_idx = -1;
5569 if ((unsigned) v->index < new_indices.length ())
5570 new_idx = new_indices[v->index];
5572 if (new_idx >= 0)
5574 v->index = new_idx;
5575 if (removed_item)
5576 (*ts->m_agg_values)[dst_index] = *v;
5577 dst_index++;
5579 else
5580 removed_item = true;
5583 if (dst_index == 0)
5585 ggc_free (ts->m_agg_values);
5586 ts->m_agg_values = NULL;
5588 else if (removed_item)
5589 ts->m_agg_values->truncate (dst_index);
5591 return;
5594 /* Dominator walker driving the ipcp modification phase. */
5596 class ipcp_modif_dom_walker : public dom_walker
5598 public:
5599 ipcp_modif_dom_walker (struct ipa_func_body_info *fbi,
5600 vec<ipa_param_descriptor, va_gc> *descs,
5601 ipcp_transformation *ts, bool *sc)
5602 : dom_walker (CDI_DOMINATORS), m_fbi (fbi), m_descriptors (descs),
5603 m_ts (ts), m_something_changed (sc) {}
5605 edge before_dom_children (basic_block) final override;
5606 bool cleanup_eh ()
5607 { return gimple_purge_all_dead_eh_edges (m_need_eh_cleanup); }
5609 private:
5610 struct ipa_func_body_info *m_fbi;
5611 vec<ipa_param_descriptor, va_gc> *m_descriptors;
5612 ipcp_transformation *m_ts;
5613 bool *m_something_changed;
5614 auto_bitmap m_need_eh_cleanup;
5617 edge
5618 ipcp_modif_dom_walker::before_dom_children (basic_block bb)
5620 gimple_stmt_iterator gsi;
5621 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
5623 gimple *stmt = gsi_stmt (gsi);
5624 tree rhs, val, t;
5625 HOST_WIDE_INT bit_offset;
5626 poly_int64 size;
5627 int index;
5628 bool by_ref, vce;
5630 if (!gimple_assign_load_p (stmt))
5631 continue;
5632 rhs = gimple_assign_rhs1 (stmt);
5633 if (!is_gimple_reg_type (TREE_TYPE (rhs)))
5634 continue;
5636 vce = false;
5637 t = rhs;
5638 while (handled_component_p (t))
5640 /* V_C_E can do things like convert an array of integers to one
5641 bigger integer and similar things we do not handle below. */
5642 if (TREE_CODE (t) == VIEW_CONVERT_EXPR)
5644 vce = true;
5645 break;
5647 t = TREE_OPERAND (t, 0);
5649 if (vce)
5650 continue;
5652 if (!ipa_load_from_parm_agg (m_fbi, m_descriptors, stmt, rhs, &index,
5653 &bit_offset, &size, &by_ref))
5654 continue;
5655 unsigned unit_offset = bit_offset / BITS_PER_UNIT;
5656 ipa_argagg_value_list avl (m_ts);
5657 tree v = avl.get_value (index, unit_offset, by_ref);
5659 if (!v
5660 || maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (v))), size))
5661 continue;
5663 gcc_checking_assert (is_gimple_ip_invariant (v));
5664 if (!useless_type_conversion_p (TREE_TYPE (rhs), TREE_TYPE (v)))
5666 if (fold_convertible_p (TREE_TYPE (rhs), v))
5667 val = fold_build1 (NOP_EXPR, TREE_TYPE (rhs), v);
5668 else if (TYPE_SIZE (TREE_TYPE (rhs))
5669 == TYPE_SIZE (TREE_TYPE (v)))
5670 val = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (rhs), v);
5671 else
5673 if (dump_file)
5675 fprintf (dump_file, " const ");
5676 print_generic_expr (dump_file, v);
5677 fprintf (dump_file, " can't be converted to type of ");
5678 print_generic_expr (dump_file, rhs);
5679 fprintf (dump_file, "\n");
5681 continue;
5684 else
5685 val = v;
5687 if (dump_file && (dump_flags & TDF_DETAILS))
5689 fprintf (dump_file, "Modifying stmt:\n ");
5690 print_gimple_stmt (dump_file, stmt, 0);
5692 gimple_assign_set_rhs_from_tree (&gsi, val);
5693 update_stmt (stmt);
5695 if (dump_file && (dump_flags & TDF_DETAILS))
5697 fprintf (dump_file, "into:\n ");
5698 print_gimple_stmt (dump_file, stmt, 0);
5699 fprintf (dump_file, "\n");
5702 *m_something_changed = true;
5703 if (maybe_clean_eh_stmt (stmt))
5704 bitmap_set_bit (m_need_eh_cleanup, bb->index);
5706 return NULL;
5709 /* If IPA-CP discovered a constant in parameter PARM at OFFSET of a given SIZE
5710 - whether passed by reference or not is given by BY_REF - return that
5711 constant. Otherwise return NULL_TREE. The is supposed to be used only
5712 after clone materialization and transformation is done (because it asserts
5713 that killed constants have been pruned). */
5715 tree
5716 ipcp_get_aggregate_const (struct function *func, tree parm, bool by_ref,
5717 HOST_WIDE_INT bit_offset, HOST_WIDE_INT bit_size)
5719 cgraph_node *node = cgraph_node::get (func->decl);
5720 ipcp_transformation *ts = ipcp_get_transformation_summary (node);
5722 if (!ts || !ts->m_agg_values)
5723 return NULL_TREE;
5725 int index = ts->get_param_index (func->decl, parm);
5726 if (index < 0)
5727 return NULL_TREE;
5729 ipa_argagg_value_list avl (ts);
5730 unsigned unit_offset = bit_offset / BITS_PER_UNIT;
5731 const ipa_argagg_value *av = avl.get_elt (index, unit_offset);
5732 if (!av || av->by_ref != by_ref)
5733 return NULL_TREE;
5734 gcc_assert (!av->killed);
5735 tree v = av->value;
5736 if (!v
5737 || maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (v))), bit_size))
5738 return NULL_TREE;
5740 return v;
5743 /* Return true if we have recorded VALUE and MASK about PARM.
5744 Set VALUE and MASk accordingly. */
5746 bool
5747 ipcp_get_parm_bits (tree parm, tree *value, widest_int *mask)
5749 cgraph_node *cnode = cgraph_node::get (current_function_decl);
5750 ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
5751 if (!ts
5752 || vec_safe_length (ts->m_vr) == 0
5753 || !irange::supports_p (TREE_TYPE (parm)))
5754 return false;
5756 int i = ts->get_param_index (current_function_decl, parm);
5757 if (i < 0)
5758 return false;
5759 clone_info *cinfo = clone_info::get (cnode);
5760 if (cinfo && cinfo->param_adjustments)
5762 i = cinfo->param_adjustments->get_original_index (i);
5763 if (i < 0)
5764 return false;
5767 vec<ipa_vr, va_gc> &vr = *ts->m_vr;
5768 if (!vr[i].known_p ())
5769 return false;
5770 Value_Range tmp;
5771 vr[i].get_vrange (tmp);
5772 if (tmp.undefined_p () || tmp.varying_p ())
5773 return false;
5774 irange &r = as_a <irange> (tmp);
5775 irange_bitmask bm = r.get_bitmask ();
5776 *mask = widest_int::from (bm.mask (), TYPE_SIGN (TREE_TYPE (parm)));
5777 *value = wide_int_to_tree (TREE_TYPE (parm), bm.value ());
5778 return true;
5781 /* Update value range of formal parameters of NODE as described in TS. */
5783 static void
5784 ipcp_update_vr (struct cgraph_node *node, ipcp_transformation *ts)
5786 if (vec_safe_is_empty (ts->m_vr))
5787 return;
5788 const vec<ipa_vr, va_gc> &vr = *ts->m_vr;
5789 unsigned count = vr.length ();
5790 if (!count)
5791 return;
5793 auto_vec<int, 16> new_indices;
5794 bool need_remapping = false;
5795 clone_info *cinfo = clone_info::get (node);
5796 if (cinfo && cinfo->param_adjustments)
5798 cinfo->param_adjustments->get_updated_indices (&new_indices);
5799 need_remapping = true;
5801 auto_vec <tree, 16> parm_decls;
5802 push_function_arg_decls (&parm_decls, node->decl);
5804 for (unsigned i = 0; i < count; ++i)
5806 tree parm;
5807 int remapped_idx;
5808 if (need_remapping)
5810 if (i >= new_indices.length ())
5811 continue;
5812 remapped_idx = new_indices[i];
5813 if (remapped_idx < 0)
5814 continue;
5816 else
5817 remapped_idx = i;
5819 parm = parm_decls[remapped_idx];
5821 gcc_checking_assert (parm);
5822 tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl), parm);
5824 if (!ddef || !is_gimple_reg (parm))
5825 continue;
5827 if (vr[i].known_p ())
5829 Value_Range tmp;
5830 vr[i].get_vrange (tmp);
5832 if (!tmp.undefined_p () && !tmp.varying_p ())
5834 if (dump_file)
5836 fprintf (dump_file, "Setting value range of param %u "
5837 "(now %i) ", i, remapped_idx);
5838 tmp.dump (dump_file);
5839 fprintf (dump_file, "]\n");
5841 set_range_info (ddef, tmp);
5843 if (POINTER_TYPE_P (TREE_TYPE (parm))
5844 && opt_for_fn (node->decl, flag_ipa_bit_cp))
5846 irange &r = as_a<irange> (tmp);
5847 irange_bitmask bm = r.get_bitmask ();
5848 unsigned tem = bm.mask ().to_uhwi ();
5849 unsigned HOST_WIDE_INT bitpos = bm.value ().to_uhwi ();
5850 unsigned align = tem & -tem;
5851 unsigned misalign = bitpos & (align - 1);
5853 if (align > 1)
5855 if (dump_file)
5857 fprintf (dump_file,
5858 "Adjusting mask for param %u to ", i);
5859 print_hex (bm.mask (), dump_file);
5860 fprintf (dump_file, "\n");
5863 if (dump_file)
5864 fprintf (dump_file,
5865 "Adjusting align: %u, misalign: %u\n",
5866 align, misalign);
5868 unsigned old_align, old_misalign;
5869 struct ptr_info_def *pi = get_ptr_info (ddef);
5870 bool old_known = get_ptr_info_alignment (pi, &old_align,
5871 &old_misalign);
5873 if (old_known && old_align > align)
5875 if (dump_file)
5877 fprintf (dump_file,
5878 "But alignment was already %u.\n",
5879 old_align);
5880 if ((old_misalign & (align - 1)) != misalign)
5881 fprintf (dump_file,
5882 "old_misalign (%u) and misalign "
5883 "(%u) mismatch\n",
5884 old_misalign, misalign);
5886 continue;
5889 if (dump_file
5890 && old_known
5891 && ((misalign & (old_align - 1)) != old_misalign))
5892 fprintf (dump_file,
5893 "old_misalign (%u) and misalign (%u) "
5894 "mismatch\n",
5895 old_misalign, misalign);
5897 set_ptr_info_alignment (pi, align, misalign);
5900 else if (dump_file && INTEGRAL_TYPE_P (TREE_TYPE (parm)))
5902 irange &r = as_a<irange> (tmp);
5903 irange_bitmask bm = r.get_bitmask ();
5904 unsigned prec = TYPE_PRECISION (TREE_TYPE (parm));
5905 if (wi::ne_p (bm.mask (), wi::shwi (-1, prec)))
5907 fprintf (dump_file,
5908 "Adjusting mask for param %u to ", i);
5909 print_hex (bm.mask (), dump_file);
5910 fprintf (dump_file, "\n");
5918 /* IPCP transformation phase doing propagation of aggregate values. */
5920 unsigned int
5921 ipcp_transform_function (struct cgraph_node *node)
5923 struct ipa_func_body_info fbi;
5924 int param_count;
5926 gcc_checking_assert (cfun);
5927 gcc_checking_assert (current_function_decl);
5929 if (dump_file)
5930 fprintf (dump_file, "Modification phase of node %s\n",
5931 node->dump_name ());
5933 ipcp_transformation *ts = ipcp_get_transformation_summary (node);
5934 if (!ts
5935 || (vec_safe_is_empty (ts->m_agg_values)
5936 && vec_safe_is_empty (ts->m_vr)))
5937 return 0;
5939 ts->maybe_create_parm_idx_map (cfun->decl);
5940 ipcp_update_vr (node, ts);
5941 if (vec_safe_is_empty (ts->m_agg_values))
5942 return 0;
5943 param_count = count_formal_params (node->decl);
5944 if (param_count == 0)
5945 return 0;
5947 adjust_agg_replacement_values (node, ts);
5948 if (vec_safe_is_empty (ts->m_agg_values))
5950 if (dump_file)
5951 fprintf (dump_file, " All affected aggregate parameters were either "
5952 "removed or converted into scalars, phase done.\n");
5953 return 0;
5955 if (dump_file)
5957 fprintf (dump_file, " Aggregate replacements:");
5958 ipa_argagg_value_list avs (ts);
5959 avs.dump (dump_file);
5962 fbi.node = node;
5963 fbi.info = NULL;
5964 fbi.bb_infos = vNULL;
5965 fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
5966 fbi.param_count = param_count;
5967 fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps);
5969 vec<ipa_param_descriptor, va_gc> *descriptors = NULL;
5970 vec_safe_grow_cleared (descriptors, param_count, true);
5971 ipa_populate_param_decls (node, *descriptors);
5972 bool modified_mem_access = false;
5973 calculate_dominance_info (CDI_DOMINATORS);
5974 ipcp_modif_dom_walker walker (&fbi, descriptors, ts, &modified_mem_access);
5975 walker.walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
5976 free_dominance_info (CDI_DOMINATORS);
5977 bool cfg_changed = walker.cleanup_eh ();
5979 int i;
5980 struct ipa_bb_info *bi;
5981 FOR_EACH_VEC_ELT (fbi.bb_infos, i, bi)
5982 free_ipa_bb_info (bi);
5983 fbi.bb_infos.release ();
5985 ts->remove_argaggs_if ([](const ipa_argagg_value &v)
5987 return v.killed;
5990 vec_free (descriptors);
5991 if (cfg_changed)
5992 delete_unreachable_blocks_update_callgraph (node, false);
5994 return modified_mem_access ? TODO_update_ssa_only_virtuals : 0;
5997 /* Record that current function return value range is VAL. */
5999 void
6000 ipa_record_return_value_range (Value_Range val)
6002 cgraph_node *n = cgraph_node::get (current_function_decl);
6003 if (!ipa_return_value_sum)
6005 if (!ipa_vr_hash_table)
6006 ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
6007 ipa_return_value_sum = new (ggc_alloc_no_dtor <ipa_return_value_sum_t> ())
6008 ipa_return_value_sum_t (symtab, true);
6009 ipa_return_value_sum->disable_insertion_hook ();
6011 ipa_return_value_sum->get_create (n)->vr = ipa_get_value_range (val);
6012 if (dump_file && (dump_flags & TDF_DETAILS))
6014 fprintf (dump_file, "Recording return range ");
6015 val.dump (dump_file);
6016 fprintf (dump_file, "\n");
6020 /* Return true if value range of DECL is known and if so initialize RANGE. */
6022 bool
6023 ipa_return_value_range (Value_Range &range, tree decl)
6025 cgraph_node *n = cgraph_node::get (decl);
6026 if (!n || !ipa_return_value_sum)
6027 return false;
6028 enum availability avail;
6029 n = n->ultimate_alias_target (&avail);
6030 if (avail < AVAIL_AVAILABLE)
6031 return false;
6032 if (n->decl != decl && !useless_type_conversion_p (TREE_TYPE (decl), TREE_TYPE (n->decl)))
6033 return false;
6034 ipa_return_value_summary *v = ipa_return_value_sum->get (n);
6035 if (!v)
6036 return false;
6037 v->vr->get_vrange (range);
6038 return true;
6041 /* Reset all state within ipa-prop.cc so that we can rerun the compiler
6042 within the same process. For use by toplev::finalize. */
6044 void
6045 ipa_prop_cc_finalize (void)
6047 if (function_insertion_hook_holder)
6048 symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
6049 function_insertion_hook_holder = NULL;
6051 if (ipa_edge_args_sum)
6052 ggc_delete (ipa_edge_args_sum);
6053 ipa_edge_args_sum = NULL;
6055 if (ipa_node_params_sum)
6056 ggc_delete (ipa_node_params_sum);
6057 ipa_node_params_sum = NULL;
6060 #include "gt-ipa-prop.h"