Daily bump.
[official-gcc.git] / gcc / ipa-prop.cc
blobe22c4f78405d290b48a43cd5cdd49ce47a7fe8a2
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, rec, ref_field, ref_offset, fld, ptr_field, delta_field;
2505 if (!gimple_assign_single_p (stmt))
2506 return NULL_TREE;
2508 rhs = gimple_assign_rhs1 (stmt);
2509 if (TREE_CODE (rhs) == COMPONENT_REF)
2511 ref_field = TREE_OPERAND (rhs, 1);
2512 rhs = TREE_OPERAND (rhs, 0);
2514 else
2515 ref_field = NULL_TREE;
2516 if (TREE_CODE (rhs) != MEM_REF)
2517 return NULL_TREE;
2518 rec = TREE_OPERAND (rhs, 0);
2519 if (TREE_CODE (rec) != ADDR_EXPR)
2520 return NULL_TREE;
2521 rec = TREE_OPERAND (rec, 0);
2522 if (TREE_CODE (rec) != PARM_DECL
2523 || !type_like_member_ptr_p (TREE_TYPE (rec), &ptr_field, &delta_field))
2524 return NULL_TREE;
2525 ref_offset = TREE_OPERAND (rhs, 1);
2527 if (use_delta)
2528 fld = delta_field;
2529 else
2530 fld = ptr_field;
2531 if (offset_p)
2532 *offset_p = int_bit_position (fld);
2534 if (ref_field)
2536 if (integer_nonzerop (ref_offset))
2537 return NULL_TREE;
2538 return ref_field == fld ? rec : NULL_TREE;
2540 else
2541 return tree_int_cst_equal (byte_position (fld), ref_offset) ? rec
2542 : NULL_TREE;
2545 /* Returns true iff T is an SSA_NAME defined by a statement. */
2547 static bool
2548 ipa_is_ssa_with_stmt_def (tree t)
2550 if (TREE_CODE (t) == SSA_NAME
2551 && !SSA_NAME_IS_DEFAULT_DEF (t))
2552 return true;
2553 else
2554 return false;
2557 /* Find the indirect call graph edge corresponding to STMT and mark it as a
2558 call to a parameter number PARAM_INDEX. NODE is the caller. Return the
2559 indirect call graph edge.
2560 If POLYMORPHIC is true record is as a destination of polymorphic call. */
2562 static struct cgraph_edge *
2563 ipa_note_param_call (struct cgraph_node *node, int param_index,
2564 gcall *stmt, bool polymorphic)
2566 struct cgraph_edge *cs;
2568 cs = node->get_edge (stmt);
2569 cs->indirect_info->param_index = param_index;
2570 cs->indirect_info->agg_contents = 0;
2571 cs->indirect_info->member_ptr = 0;
2572 cs->indirect_info->guaranteed_unmodified = 0;
2573 ipa_node_params *info = ipa_node_params_sum->get (node);
2574 ipa_set_param_used_by_indirect_call (info, param_index, true);
2575 if (cs->indirect_info->polymorphic || polymorphic)
2576 ipa_set_param_used_by_polymorphic_call (info, param_index, true);
2577 return cs;
2580 /* Analyze the CALL and examine uses of formal parameters of the caller NODE
2581 (described by INFO). PARMS_AINFO is a pointer to a vector containing
2582 intermediate information about each formal parameter. Currently it checks
2583 whether the call calls a pointer that is a formal parameter and if so, the
2584 parameter is marked with the called flag and an indirect call graph edge
2585 describing the call is created. This is very simple for ordinary pointers
2586 represented in SSA but not-so-nice when it comes to member pointers. The
2587 ugly part of this function does nothing more than trying to match the
2588 pattern of such a call. An example of such a pattern is the gimple dump
2589 below, the call is on the last line:
2591 <bb 2>:
2592 f$__delta_5 = f.__delta;
2593 f$__pfn_24 = f.__pfn;
2596 <bb 2>:
2597 f$__delta_5 = MEM[(struct *)&f];
2598 f$__pfn_24 = MEM[(struct *)&f + 4B];
2600 and a few lines below:
2602 <bb 5>
2603 D.2496_3 = (int) f$__pfn_24;
2604 D.2497_4 = D.2496_3 & 1;
2605 if (D.2497_4 != 0)
2606 goto <bb 3>;
2607 else
2608 goto <bb 4>;
2610 <bb 6>:
2611 D.2500_7 = (unsigned int) f$__delta_5;
2612 D.2501_8 = &S + D.2500_7;
2613 D.2502_9 = (int (*__vtbl_ptr_type) (void) * *) D.2501_8;
2614 D.2503_10 = *D.2502_9;
2615 D.2504_12 = f$__pfn_24 + -1;
2616 D.2505_13 = (unsigned int) D.2504_12;
2617 D.2506_14 = D.2503_10 + D.2505_13;
2618 D.2507_15 = *D.2506_14;
2619 iftmp.11_16 = (String:: *) D.2507_15;
2621 <bb 7>:
2622 # iftmp.11_1 = PHI <iftmp.11_16(3), f$__pfn_24(2)>
2623 D.2500_19 = (unsigned int) f$__delta_5;
2624 D.2508_20 = &S + D.2500_19;
2625 D.2493_21 = iftmp.11_1 (D.2508_20, 4);
2627 Such patterns are results of simple calls to a member pointer:
2629 int doprinting (int (MyString::* f)(int) const)
2631 MyString S ("somestring");
2633 return (S.*f)(4);
2636 Moreover, the function also looks for called pointers loaded from aggregates
2637 passed by value or reference. */
2639 static void
2640 ipa_analyze_indirect_call_uses (struct ipa_func_body_info *fbi, gcall *call,
2641 tree target)
2643 class ipa_node_params *info = fbi->info;
2644 HOST_WIDE_INT offset;
2645 bool by_ref;
2647 if (SSA_NAME_IS_DEFAULT_DEF (target))
2649 tree var = SSA_NAME_VAR (target);
2650 int index = ipa_get_param_decl_index (info, var);
2651 if (index >= 0)
2652 ipa_note_param_call (fbi->node, index, call, false);
2653 return;
2656 int index;
2657 gimple *def = SSA_NAME_DEF_STMT (target);
2658 bool guaranteed_unmodified;
2659 if (gimple_assign_single_p (def)
2660 && ipa_load_from_parm_agg (fbi, info->descriptors, def,
2661 gimple_assign_rhs1 (def), &index, &offset,
2662 NULL, &by_ref, &guaranteed_unmodified))
2664 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
2665 call, false);
2666 cs->indirect_info->offset = offset;
2667 cs->indirect_info->agg_contents = 1;
2668 cs->indirect_info->by_ref = by_ref;
2669 cs->indirect_info->guaranteed_unmodified = guaranteed_unmodified;
2670 return;
2673 /* Now we need to try to match the complex pattern of calling a member
2674 pointer. */
2675 if (gimple_code (def) != GIMPLE_PHI
2676 || gimple_phi_num_args (def) != 2
2677 || !POINTER_TYPE_P (TREE_TYPE (target))
2678 || TREE_CODE (TREE_TYPE (TREE_TYPE (target))) != METHOD_TYPE)
2679 return;
2681 /* First, we need to check whether one of these is a load from a member
2682 pointer that is a parameter to this function. */
2683 tree n1 = PHI_ARG_DEF (def, 0);
2684 tree n2 = PHI_ARG_DEF (def, 1);
2685 if (!ipa_is_ssa_with_stmt_def (n1) || !ipa_is_ssa_with_stmt_def (n2))
2686 return;
2687 gimple *d1 = SSA_NAME_DEF_STMT (n1);
2688 gimple *d2 = SSA_NAME_DEF_STMT (n2);
2690 tree rec;
2691 basic_block bb, virt_bb;
2692 basic_block join = gimple_bb (def);
2693 if ((rec = ipa_get_stmt_member_ptr_load_param (d1, false, &offset)))
2695 if (ipa_get_stmt_member_ptr_load_param (d2, false, NULL))
2696 return;
2698 bb = EDGE_PRED (join, 0)->src;
2699 virt_bb = gimple_bb (d2);
2701 else if ((rec = ipa_get_stmt_member_ptr_load_param (d2, false, &offset)))
2703 bb = EDGE_PRED (join, 1)->src;
2704 virt_bb = gimple_bb (d1);
2706 else
2707 return;
2709 /* Second, we need to check that the basic blocks are laid out in the way
2710 corresponding to the pattern. */
2712 if (!single_pred_p (virt_bb) || !single_succ_p (virt_bb)
2713 || single_pred (virt_bb) != bb
2714 || single_succ (virt_bb) != join)
2715 return;
2717 /* Third, let's see that the branching is done depending on the least
2718 significant bit of the pfn. */
2720 gcond *branch = safe_dyn_cast <gcond *> (*gsi_last_bb (bb));
2721 if (!branch)
2722 return;
2724 if ((gimple_cond_code (branch) != NE_EXPR
2725 && gimple_cond_code (branch) != EQ_EXPR)
2726 || !integer_zerop (gimple_cond_rhs (branch)))
2727 return;
2729 tree cond = gimple_cond_lhs (branch);
2730 if (!ipa_is_ssa_with_stmt_def (cond))
2731 return;
2733 def = SSA_NAME_DEF_STMT (cond);
2734 if (!is_gimple_assign (def)
2735 || gimple_assign_rhs_code (def) != BIT_AND_EXPR
2736 || !integer_onep (gimple_assign_rhs2 (def)))
2737 return;
2739 cond = gimple_assign_rhs1 (def);
2740 if (!ipa_is_ssa_with_stmt_def (cond))
2741 return;
2743 def = SSA_NAME_DEF_STMT (cond);
2745 if (is_gimple_assign (def)
2746 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
2748 cond = gimple_assign_rhs1 (def);
2749 if (!ipa_is_ssa_with_stmt_def (cond))
2750 return;
2751 def = SSA_NAME_DEF_STMT (cond);
2754 tree rec2;
2755 rec2 = ipa_get_stmt_member_ptr_load_param (def,
2756 (TARGET_PTRMEMFUNC_VBIT_LOCATION
2757 == ptrmemfunc_vbit_in_delta),
2758 NULL);
2759 if (rec != rec2)
2760 return;
2762 index = ipa_get_param_decl_index (info, rec);
2763 if (index >= 0
2764 && parm_preserved_before_stmt_p (fbi, index, call, rec))
2766 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
2767 call, false);
2768 cs->indirect_info->offset = offset;
2769 cs->indirect_info->agg_contents = 1;
2770 cs->indirect_info->member_ptr = 1;
2771 cs->indirect_info->guaranteed_unmodified = 1;
2774 return;
2777 /* Analyze a CALL to an OBJ_TYPE_REF which is passed in TARGET and if the
2778 object referenced in the expression is a formal parameter of the caller
2779 FBI->node (described by FBI->info), create a call note for the
2780 statement. */
2782 static void
2783 ipa_analyze_virtual_call_uses (struct ipa_func_body_info *fbi,
2784 gcall *call, tree target)
2786 tree obj = OBJ_TYPE_REF_OBJECT (target);
2787 int index;
2788 HOST_WIDE_INT anc_offset;
2790 if (!flag_devirtualize)
2791 return;
2793 if (TREE_CODE (obj) != SSA_NAME)
2794 return;
2796 class ipa_node_params *info = fbi->info;
2797 if (SSA_NAME_IS_DEFAULT_DEF (obj))
2799 if (TREE_CODE (SSA_NAME_VAR (obj)) != PARM_DECL)
2800 return;
2802 anc_offset = 0;
2803 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (obj));
2804 gcc_assert (index >= 0);
2805 if (detect_type_change_ssa (fbi, obj, obj_type_ref_class (target),
2806 call))
2807 return;
2809 else
2811 gimple *stmt = SSA_NAME_DEF_STMT (obj);
2812 tree expr;
2814 expr = get_ancestor_addr_info (stmt, &obj, &anc_offset);
2815 if (!expr)
2816 return;
2817 index = ipa_get_param_decl_index (info,
2818 SSA_NAME_VAR (TREE_OPERAND (expr, 0)));
2819 gcc_assert (index >= 0);
2820 if (detect_type_change (fbi, obj, expr, obj_type_ref_class (target),
2821 call, anc_offset))
2822 return;
2825 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
2826 call, true);
2827 class cgraph_indirect_call_info *ii = cs->indirect_info;
2828 ii->offset = anc_offset;
2829 ii->otr_token = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target));
2830 ii->otr_type = obj_type_ref_class (target);
2831 ii->polymorphic = 1;
2834 /* Analyze a call statement CALL whether and how it utilizes formal parameters
2835 of the caller (described by INFO). PARMS_AINFO is a pointer to a vector
2836 containing intermediate information about each formal parameter. */
2838 static void
2839 ipa_analyze_call_uses (struct ipa_func_body_info *fbi, gcall *call)
2841 tree target = gimple_call_fn (call);
2843 if (!target
2844 || (TREE_CODE (target) != SSA_NAME
2845 && !virtual_method_call_p (target)))
2846 return;
2848 struct cgraph_edge *cs = fbi->node->get_edge (call);
2849 /* If we previously turned the call into a direct call, there is
2850 no need to analyze. */
2851 if (cs && !cs->indirect_unknown_callee)
2852 return;
2854 if (cs->indirect_info->polymorphic && flag_devirtualize)
2856 tree instance;
2857 tree target = gimple_call_fn (call);
2858 ipa_polymorphic_call_context context (current_function_decl,
2859 target, call, &instance);
2861 gcc_checking_assert (cs->indirect_info->otr_type
2862 == obj_type_ref_class (target));
2863 gcc_checking_assert (cs->indirect_info->otr_token
2864 == tree_to_shwi (OBJ_TYPE_REF_TOKEN (target)));
2866 cs->indirect_info->vptr_changed
2867 = !context.get_dynamic_type (instance,
2868 OBJ_TYPE_REF_OBJECT (target),
2869 obj_type_ref_class (target), call,
2870 &fbi->aa_walk_budget);
2871 cs->indirect_info->context = context;
2874 if (TREE_CODE (target) == SSA_NAME)
2875 ipa_analyze_indirect_call_uses (fbi, call, target);
2876 else if (virtual_method_call_p (target))
2877 ipa_analyze_virtual_call_uses (fbi, call, target);
2881 /* Analyze the call statement STMT with respect to formal parameters (described
2882 in INFO) of caller given by FBI->NODE. Currently it only checks whether
2883 formal parameters are called. */
2885 static void
2886 ipa_analyze_stmt_uses (struct ipa_func_body_info *fbi, gimple *stmt)
2888 if (is_gimple_call (stmt))
2889 ipa_analyze_call_uses (fbi, as_a <gcall *> (stmt));
2892 /* Callback of walk_stmt_load_store_addr_ops for the visit_load.
2893 If OP is a parameter declaration, mark it as used in the info structure
2894 passed in DATA. */
2896 static bool
2897 visit_ref_for_mod_analysis (gimple *, tree op, tree, void *data)
2899 class ipa_node_params *info = (class ipa_node_params *) data;
2901 op = get_base_address (op);
2902 if (op
2903 && TREE_CODE (op) == PARM_DECL)
2905 int index = ipa_get_param_decl_index (info, op);
2906 gcc_assert (index >= 0);
2907 ipa_set_param_used (info, index, true);
2910 return false;
2913 /* Scan the statements in BB and inspect the uses of formal parameters. Store
2914 the findings in various structures of the associated ipa_node_params
2915 structure, such as parameter flags, notes etc. FBI holds various data about
2916 the function being analyzed. */
2918 static void
2919 ipa_analyze_params_uses_in_bb (struct ipa_func_body_info *fbi, basic_block bb)
2921 gimple_stmt_iterator gsi;
2922 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2924 gimple *stmt = gsi_stmt (gsi);
2926 if (is_gimple_debug (stmt))
2927 continue;
2929 ipa_analyze_stmt_uses (fbi, stmt);
2930 walk_stmt_load_store_addr_ops (stmt, fbi->info,
2931 visit_ref_for_mod_analysis,
2932 visit_ref_for_mod_analysis,
2933 visit_ref_for_mod_analysis);
2935 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2936 walk_stmt_load_store_addr_ops (gsi_stmt (gsi), fbi->info,
2937 visit_ref_for_mod_analysis,
2938 visit_ref_for_mod_analysis,
2939 visit_ref_for_mod_analysis);
2942 /* Return true EXPR is a load from a dereference of SSA_NAME NAME. */
2944 static bool
2945 load_from_dereferenced_name (tree expr, tree name)
2947 tree base = get_base_address (expr);
2948 return (TREE_CODE (base) == MEM_REF
2949 && TREE_OPERAND (base, 0) == name);
2952 /* Calculate controlled uses of parameters of NODE. */
2954 static void
2955 ipa_analyze_controlled_uses (struct cgraph_node *node)
2957 ipa_node_params *info = ipa_node_params_sum->get (node);
2959 for (int i = 0; i < ipa_get_param_count (info); i++)
2961 tree parm = ipa_get_param (info, i);
2962 int call_uses = 0;
2963 bool load_dereferenced = false;
2965 /* For SSA regs see if parameter is used. For non-SSA we compute
2966 the flag during modification analysis. */
2967 if (is_gimple_reg (parm))
2969 tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl),
2970 parm);
2971 if (ddef && !has_zero_uses (ddef))
2973 imm_use_iterator imm_iter;
2974 gimple *stmt;
2976 ipa_set_param_used (info, i, true);
2977 FOR_EACH_IMM_USE_STMT (stmt, imm_iter, ddef)
2979 if (is_gimple_debug (stmt))
2980 continue;
2982 int all_stmt_uses = 0;
2983 use_operand_p use_p;
2984 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
2985 all_stmt_uses++;
2987 if (is_gimple_call (stmt))
2989 if (gimple_call_internal_p (stmt))
2991 call_uses = IPA_UNDESCRIBED_USE;
2992 break;
2994 int recognized_stmt_uses;
2995 if (gimple_call_fn (stmt) == ddef)
2996 recognized_stmt_uses = 1;
2997 else
2998 recognized_stmt_uses = 0;
2999 unsigned arg_count = gimple_call_num_args (stmt);
3000 for (unsigned i = 0; i < arg_count; i++)
3002 tree arg = gimple_call_arg (stmt, i);
3003 if (arg == ddef)
3004 recognized_stmt_uses++;
3005 else if (load_from_dereferenced_name (arg, ddef))
3007 load_dereferenced = true;
3008 recognized_stmt_uses++;
3012 if (recognized_stmt_uses != all_stmt_uses)
3014 call_uses = IPA_UNDESCRIBED_USE;
3015 break;
3017 if (call_uses >= 0)
3018 call_uses += all_stmt_uses;
3020 else if (gimple_assign_single_p (stmt))
3022 tree rhs = gimple_assign_rhs1 (stmt);
3023 if (all_stmt_uses != 1
3024 || !load_from_dereferenced_name (rhs, ddef))
3026 call_uses = IPA_UNDESCRIBED_USE;
3027 break;
3029 load_dereferenced = true;
3031 else
3033 call_uses = IPA_UNDESCRIBED_USE;
3034 break;
3038 else
3039 call_uses = 0;
3041 else
3042 call_uses = IPA_UNDESCRIBED_USE;
3043 ipa_set_controlled_uses (info, i, call_uses);
3044 ipa_set_param_load_dereferenced (info, i, load_dereferenced);
3048 /* Free stuff in BI. */
3050 static void
3051 free_ipa_bb_info (struct ipa_bb_info *bi)
3053 bi->cg_edges.release ();
3054 bi->param_aa_statuses.release ();
3057 /* Dominator walker driving the analysis. */
3059 class analysis_dom_walker : public dom_walker
3061 public:
3062 analysis_dom_walker (struct ipa_func_body_info *fbi)
3063 : dom_walker (CDI_DOMINATORS), m_fbi (fbi) {}
3065 edge before_dom_children (basic_block) final override;
3067 private:
3068 struct ipa_func_body_info *m_fbi;
3071 edge
3072 analysis_dom_walker::before_dom_children (basic_block bb)
3074 ipa_analyze_params_uses_in_bb (m_fbi, bb);
3075 ipa_compute_jump_functions_for_bb (m_fbi, bb);
3076 return NULL;
3079 /* Release body info FBI. */
3081 void
3082 ipa_release_body_info (struct ipa_func_body_info *fbi)
3084 int i;
3085 struct ipa_bb_info *bi;
3087 FOR_EACH_VEC_ELT (fbi->bb_infos, i, bi)
3088 free_ipa_bb_info (bi);
3089 fbi->bb_infos.release ();
3092 /* Initialize the array describing properties of formal parameters
3093 of NODE, analyze their uses and compute jump functions associated
3094 with actual arguments of calls from within NODE. */
3096 void
3097 ipa_analyze_node (struct cgraph_node *node)
3099 struct ipa_func_body_info fbi;
3100 class ipa_node_params *info;
3102 ipa_check_create_node_params ();
3103 ipa_check_create_edge_args ();
3104 info = ipa_node_params_sum->get_create (node);
3106 if (info->analysis_done)
3107 return;
3108 info->analysis_done = 1;
3110 if (ipa_func_spec_opts_forbid_analysis_p (node)
3111 || (count_formal_params (node->decl)
3112 >= (1 << IPA_PROP_ARG_INDEX_LIMIT_BITS)))
3114 gcc_assert (!ipa_get_param_count (info));
3115 return;
3118 struct function *func = DECL_STRUCT_FUNCTION (node->decl);
3119 push_cfun (func);
3120 calculate_dominance_info (CDI_DOMINATORS);
3121 ipa_initialize_node_params (node);
3122 ipa_analyze_controlled_uses (node);
3124 fbi.node = node;
3125 fbi.info = info;
3126 fbi.bb_infos = vNULL;
3127 fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
3128 fbi.param_count = ipa_get_param_count (info);
3129 fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps);
3131 for (struct cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
3133 ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
3134 bi->cg_edges.safe_push (cs);
3137 for (struct cgraph_edge *cs = node->indirect_calls; cs; cs = cs->next_callee)
3139 ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
3140 bi->cg_edges.safe_push (cs);
3143 enable_ranger (cfun, false);
3144 analysis_dom_walker (&fbi).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
3145 disable_ranger (cfun);
3147 ipa_release_body_info (&fbi);
3148 free_dominance_info (CDI_DOMINATORS);
3149 pop_cfun ();
3152 /* Update the jump functions associated with call graph edge E when the call
3153 graph edge CS is being inlined, assuming that E->caller is already (possibly
3154 indirectly) inlined into CS->callee and that E has not been inlined. */
3156 static void
3157 update_jump_functions_after_inlining (struct cgraph_edge *cs,
3158 struct cgraph_edge *e)
3160 ipa_edge_args *top = ipa_edge_args_sum->get (cs);
3161 ipa_edge_args *args = ipa_edge_args_sum->get (e);
3162 if (!args)
3163 return;
3164 int count = ipa_get_cs_argument_count (args);
3165 int i;
3167 for (i = 0; i < count; i++)
3169 struct ipa_jump_func *dst = ipa_get_ith_jump_func (args, i);
3170 class ipa_polymorphic_call_context *dst_ctx
3171 = ipa_get_ith_polymorhic_call_context (args, i);
3173 if (dst->agg.items)
3175 struct ipa_agg_jf_item *item;
3176 int j;
3178 FOR_EACH_VEC_ELT (*dst->agg.items, j, item)
3180 int dst_fid;
3181 struct ipa_jump_func *src;
3183 if (item->jftype != IPA_JF_PASS_THROUGH
3184 && item->jftype != IPA_JF_LOAD_AGG)
3185 continue;
3187 dst_fid = item->value.pass_through.formal_id;
3188 if (!top || dst_fid >= ipa_get_cs_argument_count (top))
3190 item->jftype = IPA_JF_UNKNOWN;
3191 continue;
3194 item->value.pass_through.formal_id = -1;
3195 src = ipa_get_ith_jump_func (top, dst_fid);
3196 if (src->type == IPA_JF_CONST)
3198 if (item->jftype == IPA_JF_PASS_THROUGH
3199 && item->value.pass_through.operation == NOP_EXPR)
3201 item->jftype = IPA_JF_CONST;
3202 item->value.constant = src->value.constant.value;
3203 continue;
3206 else if (src->type == IPA_JF_PASS_THROUGH
3207 && src->value.pass_through.operation == NOP_EXPR)
3209 if (item->jftype == IPA_JF_PASS_THROUGH
3210 || !item->value.load_agg.by_ref
3211 || src->value.pass_through.agg_preserved)
3212 item->value.pass_through.formal_id
3213 = src->value.pass_through.formal_id;
3215 else if (src->type == IPA_JF_ANCESTOR)
3217 if (item->jftype == IPA_JF_PASS_THROUGH)
3219 if (!src->value.ancestor.offset)
3220 item->value.pass_through.formal_id
3221 = src->value.ancestor.formal_id;
3223 else if (src->value.ancestor.agg_preserved)
3225 gcc_checking_assert (item->value.load_agg.by_ref);
3227 item->value.pass_through.formal_id
3228 = src->value.ancestor.formal_id;
3229 item->value.load_agg.offset
3230 += src->value.ancestor.offset;
3234 if (item->value.pass_through.formal_id < 0)
3235 item->jftype = IPA_JF_UNKNOWN;
3239 if (!top)
3241 ipa_set_jf_unknown (dst);
3242 continue;
3245 if (dst->type == IPA_JF_ANCESTOR)
3247 struct ipa_jump_func *src;
3248 int dst_fid = dst->value.ancestor.formal_id;
3249 class ipa_polymorphic_call_context *src_ctx
3250 = ipa_get_ith_polymorhic_call_context (top, dst_fid);
3252 /* Variable number of arguments can cause havoc if we try to access
3253 one that does not exist in the inlined edge. So make sure we
3254 don't. */
3255 if (dst_fid >= ipa_get_cs_argument_count (top))
3257 ipa_set_jf_unknown (dst);
3258 continue;
3261 src = ipa_get_ith_jump_func (top, dst_fid);
3263 if (src_ctx && !src_ctx->useless_p ())
3265 class ipa_polymorphic_call_context ctx = *src_ctx;
3267 /* TODO: Make type preserved safe WRT contexts. */
3268 if (!ipa_get_jf_ancestor_type_preserved (dst))
3269 ctx.possible_dynamic_type_change (e->in_polymorphic_cdtor);
3270 ctx.offset_by (dst->value.ancestor.offset);
3271 if (!ctx.useless_p ())
3273 if (!dst_ctx)
3275 vec_safe_grow_cleared (args->polymorphic_call_contexts,
3276 count, true);
3277 dst_ctx = ipa_get_ith_polymorhic_call_context (args, i);
3280 dst_ctx->combine_with (ctx);
3284 /* Parameter and argument in ancestor jump function must be pointer
3285 type, which means access to aggregate must be by-reference. */
3286 gcc_assert (!src->agg.items || src->agg.by_ref);
3288 if (src->agg.items && dst->value.ancestor.agg_preserved)
3290 struct ipa_agg_jf_item *item;
3291 int j;
3293 /* Currently we do not produce clobber aggregate jump functions,
3294 replace with merging when we do. */
3295 gcc_assert (!dst->agg.items);
3297 dst->agg.items = vec_safe_copy (src->agg.items);
3298 dst->agg.by_ref = src->agg.by_ref;
3299 FOR_EACH_VEC_SAFE_ELT (dst->agg.items, j, item)
3300 item->offset -= dst->value.ancestor.offset;
3303 if (src->type == IPA_JF_PASS_THROUGH
3304 && src->value.pass_through.operation == NOP_EXPR)
3306 dst->value.ancestor.formal_id = src->value.pass_through.formal_id;
3307 dst->value.ancestor.agg_preserved &=
3308 src->value.pass_through.agg_preserved;
3310 else if (src->type == IPA_JF_ANCESTOR)
3312 dst->value.ancestor.formal_id = src->value.ancestor.formal_id;
3313 dst->value.ancestor.offset += src->value.ancestor.offset;
3314 dst->value.ancestor.agg_preserved &=
3315 src->value.ancestor.agg_preserved;
3316 dst->value.ancestor.keep_null |= src->value.ancestor.keep_null;
3318 else
3319 ipa_set_jf_unknown (dst);
3321 else if (dst->type == IPA_JF_PASS_THROUGH)
3323 struct ipa_jump_func *src;
3324 /* We must check range due to calls with variable number of arguments
3325 and we cannot combine jump functions with operations. */
3326 if (dst->value.pass_through.operation == NOP_EXPR
3327 && (top && dst->value.pass_through.formal_id
3328 < ipa_get_cs_argument_count (top)))
3330 int dst_fid = dst->value.pass_through.formal_id;
3331 src = ipa_get_ith_jump_func (top, dst_fid);
3332 bool dst_agg_p = ipa_get_jf_pass_through_agg_preserved (dst);
3333 class ipa_polymorphic_call_context *src_ctx
3334 = ipa_get_ith_polymorhic_call_context (top, dst_fid);
3336 if (src_ctx && !src_ctx->useless_p ())
3338 class ipa_polymorphic_call_context ctx = *src_ctx;
3340 /* TODO: Make type preserved safe WRT contexts. */
3341 if (!ipa_get_jf_pass_through_type_preserved (dst))
3342 ctx.possible_dynamic_type_change (e->in_polymorphic_cdtor);
3343 if (!ctx.useless_p ())
3345 if (!dst_ctx)
3347 vec_safe_grow_cleared (args->polymorphic_call_contexts,
3348 count, true);
3349 dst_ctx = ipa_get_ith_polymorhic_call_context (args, i);
3351 dst_ctx->combine_with (ctx);
3354 switch (src->type)
3356 case IPA_JF_UNKNOWN:
3357 ipa_set_jf_unknown (dst);
3358 break;
3359 case IPA_JF_CONST:
3361 bool rd = ipa_get_jf_pass_through_refdesc_decremented (dst);
3362 ipa_set_jf_cst_copy (dst, src);
3363 if (rd)
3364 ipa_zap_jf_refdesc (dst);
3367 break;
3369 case IPA_JF_PASS_THROUGH:
3371 int formal_id = ipa_get_jf_pass_through_formal_id (src);
3372 enum tree_code operation;
3373 operation = ipa_get_jf_pass_through_operation (src);
3375 if (operation == NOP_EXPR)
3377 bool agg_p;
3378 agg_p = dst_agg_p
3379 && ipa_get_jf_pass_through_agg_preserved (src);
3380 ipa_set_jf_simple_pass_through (dst, formal_id, agg_p);
3382 else if (TREE_CODE_CLASS (operation) == tcc_unary)
3383 ipa_set_jf_unary_pass_through (dst, formal_id, operation);
3384 else
3386 tree operand = ipa_get_jf_pass_through_operand (src);
3387 ipa_set_jf_arith_pass_through (dst, formal_id, operand,
3388 operation);
3390 break;
3392 case IPA_JF_ANCESTOR:
3394 bool agg_p;
3395 agg_p = dst_agg_p
3396 && ipa_get_jf_ancestor_agg_preserved (src);
3397 ipa_set_ancestor_jf (dst,
3398 ipa_get_jf_ancestor_offset (src),
3399 ipa_get_jf_ancestor_formal_id (src),
3400 agg_p,
3401 ipa_get_jf_ancestor_keep_null (src));
3402 break;
3404 default:
3405 gcc_unreachable ();
3408 if (src->agg.items
3409 && (dst_agg_p || !src->agg.by_ref))
3411 /* Currently we do not produce clobber aggregate jump
3412 functions, replace with merging when we do. */
3413 gcc_assert (!dst->agg.items);
3415 dst->agg.by_ref = src->agg.by_ref;
3416 dst->agg.items = vec_safe_copy (src->agg.items);
3419 else
3420 ipa_set_jf_unknown (dst);
3425 /* If TARGET is an addr_expr of a function declaration, make it the
3426 (SPECULATIVE)destination of an indirect edge IE and return the edge.
3427 Otherwise, return NULL. */
3429 struct cgraph_edge *
3430 ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
3431 bool speculative)
3433 struct cgraph_node *callee;
3434 bool unreachable = false;
3436 if (TREE_CODE (target) == ADDR_EXPR)
3437 target = TREE_OPERAND (target, 0);
3438 if (TREE_CODE (target) != FUNCTION_DECL)
3440 target = canonicalize_constructor_val (target, NULL);
3441 if (!target || TREE_CODE (target) != FUNCTION_DECL)
3443 /* Member pointer call that goes through a VMT lookup. */
3444 if (ie->indirect_info->member_ptr
3445 /* Or if target is not an invariant expression and we do not
3446 know if it will evaulate to function at runtime.
3447 This can happen when folding through &VAR, where &VAR
3448 is IP invariant, but VAR itself is not.
3450 TODO: Revisit this when GCC 5 is branched. It seems that
3451 member_ptr check is not needed and that we may try to fold
3452 the expression and see if VAR is readonly. */
3453 || !is_gimple_ip_invariant (target))
3455 if (dump_enabled_p ())
3457 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
3458 "discovered direct call non-invariant %s\n",
3459 ie->caller->dump_name ());
3461 return NULL;
3465 if (dump_enabled_p ())
3467 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
3468 "discovered direct call to non-function in %s, "
3469 "making it __builtin_unreachable\n",
3470 ie->caller->dump_name ());
3473 target = builtin_decl_unreachable ();
3474 callee = cgraph_node::get_create (target);
3475 unreachable = true;
3477 else
3478 callee = cgraph_node::get (target);
3480 else
3481 callee = cgraph_node::get (target);
3483 /* Because may-edges are not explicitely represented and vtable may be external,
3484 we may create the first reference to the object in the unit. */
3485 if (!callee || callee->inlined_to)
3488 /* We are better to ensure we can refer to it.
3489 In the case of static functions we are out of luck, since we already
3490 removed its body. In the case of public functions we may or may
3491 not introduce the reference. */
3492 if (!canonicalize_constructor_val (target, NULL)
3493 || !TREE_PUBLIC (target))
3495 if (dump_file)
3496 fprintf (dump_file, "ipa-prop: Discovered call to a known target "
3497 "(%s -> %s) but cannot refer to it. Giving up.\n",
3498 ie->caller->dump_name (),
3499 ie->callee->dump_name ());
3500 return NULL;
3502 callee = cgraph_node::get_create (target);
3505 /* If the edge is already speculated. */
3506 if (speculative && ie->speculative)
3508 if (dump_file)
3510 cgraph_edge *e2 = ie->speculative_call_for_target (callee);
3511 if (!e2)
3513 if (dump_file)
3514 fprintf (dump_file, "ipa-prop: Discovered call to a "
3515 "speculative target (%s -> %s) but the call is "
3516 "already speculated to different target. "
3517 "Giving up.\n",
3518 ie->caller->dump_name (), callee->dump_name ());
3520 else
3522 if (dump_file)
3523 fprintf (dump_file,
3524 "ipa-prop: Discovered call to a speculative target "
3525 "(%s -> %s) this agree with previous speculation.\n",
3526 ie->caller->dump_name (), callee->dump_name ());
3529 return NULL;
3532 if (!dbg_cnt (devirt))
3533 return NULL;
3535 ipa_check_create_node_params ();
3537 /* We cannot make edges to inline clones. It is bug that someone removed
3538 the cgraph node too early. */
3539 gcc_assert (!callee->inlined_to);
3541 if (dump_file && !unreachable)
3543 fprintf (dump_file, "ipa-prop: Discovered %s call to a %s target "
3544 "(%s -> %s), for stmt ",
3545 ie->indirect_info->polymorphic ? "a virtual" : "an indirect",
3546 speculative ? "speculative" : "known",
3547 ie->caller->dump_name (),
3548 callee->dump_name ());
3549 if (ie->call_stmt)
3550 print_gimple_stmt (dump_file, ie->call_stmt, 2, TDF_SLIM);
3551 else
3552 fprintf (dump_file, "with uid %i\n", ie->lto_stmt_uid);
3554 if (dump_enabled_p ())
3556 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
3557 "converting indirect call in %s to direct call to %s\n",
3558 ie->caller->dump_name (), callee->dump_name ());
3560 if (!speculative)
3562 struct cgraph_edge *orig = ie;
3563 ie = cgraph_edge::make_direct (ie, callee);
3564 /* If we resolved speculative edge the cost is already up to date
3565 for direct call (adjusted by inline_edge_duplication_hook). */
3566 if (ie == orig)
3568 ipa_call_summary *es = ipa_call_summaries->get (ie);
3569 es->call_stmt_size -= (eni_size_weights.indirect_call_cost
3570 - eni_size_weights.call_cost);
3571 es->call_stmt_time -= (eni_time_weights.indirect_call_cost
3572 - eni_time_weights.call_cost);
3575 else
3577 if (!callee->can_be_discarded_p ())
3579 cgraph_node *alias;
3580 alias = dyn_cast<cgraph_node *> (callee->noninterposable_alias ());
3581 if (alias)
3582 callee = alias;
3584 /* make_speculative will update ie's cost to direct call cost. */
3585 ie = ie->make_speculative
3586 (callee, ie->count.apply_scale (8, 10));
3589 return ie;
3592 /* Attempt to locate an interprocedural constant at a given REQ_OFFSET in
3593 CONSTRUCTOR and return it. Return NULL if the search fails for some
3594 reason. */
3596 static tree
3597 find_constructor_constant_at_offset (tree constructor, HOST_WIDE_INT req_offset)
3599 tree type = TREE_TYPE (constructor);
3600 if (TREE_CODE (type) != ARRAY_TYPE
3601 && TREE_CODE (type) != RECORD_TYPE)
3602 return NULL;
3604 unsigned ix;
3605 tree index, val;
3606 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (constructor), ix, index, val)
3608 HOST_WIDE_INT elt_offset;
3609 if (TREE_CODE (type) == ARRAY_TYPE)
3611 offset_int off;
3612 tree unit_size = TYPE_SIZE_UNIT (TREE_TYPE (type));
3613 gcc_assert (TREE_CODE (unit_size) == INTEGER_CST);
3615 if (index)
3617 if (TREE_CODE (index) == RANGE_EXPR)
3618 off = wi::to_offset (TREE_OPERAND (index, 0));
3619 else
3620 off = wi::to_offset (index);
3621 if (TYPE_DOMAIN (type) && TYPE_MIN_VALUE (TYPE_DOMAIN (type)))
3623 tree low_bound = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
3624 gcc_assert (TREE_CODE (unit_size) == INTEGER_CST);
3625 off = wi::sext (off - wi::to_offset (low_bound),
3626 TYPE_PRECISION (TREE_TYPE (index)));
3628 off *= wi::to_offset (unit_size);
3629 /* ??? Handle more than just the first index of a
3630 RANGE_EXPR. */
3632 else
3633 off = wi::to_offset (unit_size) * ix;
3635 off = wi::lshift (off, LOG2_BITS_PER_UNIT);
3636 if (!wi::fits_shwi_p (off) || wi::neg_p (off))
3637 continue;
3638 elt_offset = off.to_shwi ();
3640 else if (TREE_CODE (type) == RECORD_TYPE)
3642 gcc_checking_assert (index && TREE_CODE (index) == FIELD_DECL);
3643 if (DECL_BIT_FIELD (index))
3644 continue;
3645 elt_offset = int_bit_position (index);
3647 else
3648 gcc_unreachable ();
3650 if (elt_offset > req_offset)
3651 return NULL;
3653 if (TREE_CODE (val) == CONSTRUCTOR)
3654 return find_constructor_constant_at_offset (val,
3655 req_offset - elt_offset);
3657 if (elt_offset == req_offset
3658 && is_gimple_reg_type (TREE_TYPE (val))
3659 && is_gimple_ip_invariant (val))
3660 return val;
3662 return NULL;
3665 /* Check whether SCALAR could be used to look up an aggregate interprocedural
3666 invariant from a static constructor and if so, return it. Otherwise return
3667 NULL. */
3669 tree
3670 ipa_find_agg_cst_from_init (tree scalar, HOST_WIDE_INT offset, bool by_ref)
3672 if (by_ref)
3674 if (TREE_CODE (scalar) != ADDR_EXPR)
3675 return NULL;
3676 scalar = TREE_OPERAND (scalar, 0);
3679 if (!VAR_P (scalar)
3680 || !is_global_var (scalar)
3681 || !TREE_READONLY (scalar)
3682 || !DECL_INITIAL (scalar)
3683 || TREE_CODE (DECL_INITIAL (scalar)) != CONSTRUCTOR)
3684 return NULL;
3686 return find_constructor_constant_at_offset (DECL_INITIAL (scalar), offset);
3689 /* Retrieve value from AGG_JFUNC for the given OFFSET or return NULL if there
3690 is none. BY_REF specifies whether the value has to be passed by reference
3691 or by value. */
3693 static tree
3694 ipa_find_agg_cst_from_jfunc_items (struct ipa_agg_jump_function *agg_jfunc,
3695 ipa_node_params *src_info,
3696 cgraph_node *src_node,
3697 HOST_WIDE_INT offset, bool by_ref)
3699 if (by_ref != agg_jfunc->by_ref)
3700 return NULL_TREE;
3702 for (const ipa_agg_jf_item &item : agg_jfunc->items)
3703 if (item.offset == offset)
3704 return ipa_agg_value_from_jfunc (src_info, src_node, &item);
3706 return NULL_TREE;
3709 /* Remove a reference to SYMBOL from the list of references of a node given by
3710 reference description RDESC. Return true if the reference has been
3711 successfully found and removed. */
3713 static bool
3714 remove_described_reference (symtab_node *symbol, struct ipa_cst_ref_desc *rdesc)
3716 struct ipa_ref *to_del;
3717 struct cgraph_edge *origin;
3719 origin = rdesc->cs;
3720 if (!origin)
3721 return false;
3722 to_del = origin->caller->find_reference (symbol, origin->call_stmt,
3723 origin->lto_stmt_uid, IPA_REF_ADDR);
3724 if (!to_del)
3725 return false;
3727 to_del->remove_reference ();
3728 if (dump_file)
3729 fprintf (dump_file, "ipa-prop: Removed a reference from %s to %s.\n",
3730 origin->caller->dump_name (), symbol->dump_name ());
3731 return true;
3734 /* If JFUNC has a reference description with refcount different from
3735 IPA_UNDESCRIBED_USE, return the reference description, otherwise return
3736 NULL. JFUNC must be a constant jump function. */
3738 static struct ipa_cst_ref_desc *
3739 jfunc_rdesc_usable (struct ipa_jump_func *jfunc)
3741 struct ipa_cst_ref_desc *rdesc = ipa_get_jf_constant_rdesc (jfunc);
3742 if (rdesc && rdesc->refcount != IPA_UNDESCRIBED_USE)
3743 return rdesc;
3744 else
3745 return NULL;
3748 /* If the value of constant jump function JFUNC is an address of a function
3749 declaration, return the associated call graph node. Otherwise return
3750 NULL. */
3752 static symtab_node *
3753 symtab_node_for_jfunc (struct ipa_jump_func *jfunc)
3755 gcc_checking_assert (jfunc->type == IPA_JF_CONST);
3756 tree cst = ipa_get_jf_constant (jfunc);
3757 if (TREE_CODE (cst) != ADDR_EXPR
3758 || (TREE_CODE (TREE_OPERAND (cst, 0)) != FUNCTION_DECL
3759 && TREE_CODE (TREE_OPERAND (cst, 0)) != VAR_DECL))
3760 return NULL;
3762 return symtab_node::get (TREE_OPERAND (cst, 0));
3766 /* If JFUNC is a constant jump function with a usable rdesc, decrement its
3767 refcount and if it hits zero, remove reference to SYMBOL from the caller of
3768 the edge specified in the rdesc. Return false if either the symbol or the
3769 reference could not be found, otherwise return true. */
3771 static bool
3772 try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc)
3774 struct ipa_cst_ref_desc *rdesc;
3775 if (jfunc->type == IPA_JF_CONST
3776 && (rdesc = jfunc_rdesc_usable (jfunc))
3777 && --rdesc->refcount == 0)
3779 symtab_node *symbol = symtab_node_for_jfunc (jfunc);
3780 if (!symbol)
3781 return false;
3783 return remove_described_reference (symbol, rdesc);
3785 return true;
3788 /* Try to find a destination for indirect edge IE that corresponds to a simple
3789 call or a call of a member function pointer and where the destination is a
3790 pointer formal parameter described by jump function JFUNC. TARGET_TYPE is
3791 the type of the parameter to which the result of JFUNC is passed. If it can
3792 be determined, return the newly direct edge, otherwise return NULL.
3793 NEW_ROOT and NEW_ROOT_INFO is the node and its info that JFUNC lattices are
3794 relative to. */
3796 static struct cgraph_edge *
3797 try_make_edge_direct_simple_call (struct cgraph_edge *ie,
3798 struct ipa_jump_func *jfunc, tree target_type,
3799 struct cgraph_node *new_root,
3800 class ipa_node_params *new_root_info)
3802 struct cgraph_edge *cs;
3803 tree target = NULL_TREE;
3804 bool agg_contents = ie->indirect_info->agg_contents;
3805 tree scalar = ipa_value_from_jfunc (new_root_info, jfunc, target_type);
3806 if (agg_contents)
3808 if (scalar)
3809 target = ipa_find_agg_cst_from_init (scalar, ie->indirect_info->offset,
3810 ie->indirect_info->by_ref);
3811 if (!target && ie->indirect_info->guaranteed_unmodified)
3812 target = ipa_find_agg_cst_from_jfunc_items (&jfunc->agg, new_root_info,
3813 new_root,
3814 ie->indirect_info->offset,
3815 ie->indirect_info->by_ref);
3817 else
3818 target = scalar;
3819 if (!target)
3820 return NULL;
3821 cs = ipa_make_edge_direct_to_target (ie, target);
3823 if (cs && !agg_contents)
3825 bool ok;
3826 gcc_checking_assert (cs->callee
3827 && (cs != ie
3828 || jfunc->type != IPA_JF_CONST
3829 || !symtab_node_for_jfunc (jfunc)
3830 || cs->callee == symtab_node_for_jfunc (jfunc)));
3831 ok = try_decrement_rdesc_refcount (jfunc);
3832 gcc_checking_assert (ok);
3835 return cs;
3838 /* Return the target to be used in cases of impossible devirtualization. IE
3839 and target (the latter can be NULL) are dumped when dumping is enabled. */
3841 tree
3842 ipa_impossible_devirt_target (struct cgraph_edge *ie, tree target)
3844 if (dump_file)
3846 if (target)
3847 fprintf (dump_file,
3848 "Type inconsistent devirtualization: %s->%s\n",
3849 ie->caller->dump_name (),
3850 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (target)));
3851 else
3852 fprintf (dump_file,
3853 "No devirtualization target in %s\n",
3854 ie->caller->dump_name ());
3856 tree new_target = builtin_decl_unreachable ();
3857 cgraph_node::get_create (new_target);
3858 return new_target;
3861 /* Try to find a destination for indirect edge IE that corresponds to a virtual
3862 call based on a formal parameter which is described by jump function JFUNC
3863 and if it can be determined, make it direct and return the direct edge.
3864 Otherwise, return NULL. CTX describes the polymorphic context that the
3865 parameter the call is based on brings along with it. NEW_ROOT and
3866 NEW_ROOT_INFO is the node and its info that JFUNC lattices are relative
3867 to. */
3869 static struct cgraph_edge *
3870 try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
3871 struct ipa_jump_func *jfunc,
3872 class ipa_polymorphic_call_context ctx,
3873 struct cgraph_node *new_root,
3874 class ipa_node_params *new_root_info)
3876 tree target = NULL;
3877 bool speculative = false;
3879 if (!opt_for_fn (ie->caller->decl, flag_devirtualize))
3880 return NULL;
3882 gcc_assert (!ie->indirect_info->by_ref);
3884 /* Try to do lookup via known virtual table pointer value. */
3885 if (!ie->indirect_info->vptr_changed
3886 || opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively))
3888 tree vtable;
3889 unsigned HOST_WIDE_INT offset;
3890 tree t = NULL_TREE;
3891 if (jfunc->type == IPA_JF_CONST)
3892 t = ipa_find_agg_cst_from_init (ipa_get_jf_constant (jfunc),
3893 ie->indirect_info->offset, true);
3894 if (!t)
3895 t = ipa_find_agg_cst_from_jfunc_items (&jfunc->agg, new_root_info,
3896 new_root,
3897 ie->indirect_info->offset, true);
3898 if (t && vtable_pointer_value_to_vtable (t, &vtable, &offset))
3900 bool can_refer;
3901 t = gimple_get_virt_method_for_vtable (ie->indirect_info->otr_token,
3902 vtable, offset, &can_refer);
3903 if (can_refer)
3905 if (!t
3906 || fndecl_built_in_p (t, BUILT_IN_UNREACHABLE,
3907 BUILT_IN_UNREACHABLE_TRAP)
3908 || !possible_polymorphic_call_target_p
3909 (ie, cgraph_node::get (t)))
3911 /* Do not speculate builtin_unreachable, it is stupid! */
3912 if (!ie->indirect_info->vptr_changed)
3913 target = ipa_impossible_devirt_target (ie, target);
3914 else
3915 target = NULL;
3917 else
3919 target = t;
3920 speculative = ie->indirect_info->vptr_changed;
3926 ipa_polymorphic_call_context ie_context (ie);
3927 vec <cgraph_node *>targets;
3928 bool final;
3930 ctx.offset_by (ie->indirect_info->offset);
3931 if (ie->indirect_info->vptr_changed)
3932 ctx.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
3933 ie->indirect_info->otr_type);
3934 ctx.combine_with (ie_context, ie->indirect_info->otr_type);
3935 targets = possible_polymorphic_call_targets
3936 (ie->indirect_info->otr_type,
3937 ie->indirect_info->otr_token,
3938 ctx, &final);
3939 if (final && targets.length () <= 1)
3941 speculative = false;
3942 if (targets.length () == 1)
3943 target = targets[0]->decl;
3944 else
3945 target = ipa_impossible_devirt_target (ie, NULL_TREE);
3947 else if (!target && opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively)
3948 && !ie->speculative && ie->maybe_hot_p ())
3950 cgraph_node *n;
3951 n = try_speculative_devirtualization (ie->indirect_info->otr_type,
3952 ie->indirect_info->otr_token,
3953 ie->indirect_info->context);
3954 if (n)
3956 target = n->decl;
3957 speculative = true;
3961 if (target)
3963 if (!possible_polymorphic_call_target_p
3964 (ie, cgraph_node::get_create (target)))
3966 if (speculative)
3967 return NULL;
3968 target = ipa_impossible_devirt_target (ie, target);
3970 return ipa_make_edge_direct_to_target (ie, target, speculative);
3972 else
3973 return NULL;
3976 /* Update the param called notes associated with NODE when CS is being inlined,
3977 assuming NODE is (potentially indirectly) inlined into CS->callee.
3978 Moreover, if the callee is discovered to be constant, create a new cgraph
3979 edge for it. Newly discovered indirect edges will be added to *NEW_EDGES,
3980 unless NEW_EDGES is NULL. Return true iff a new edge(s) were created. */
3982 static bool
3983 update_indirect_edges_after_inlining (struct cgraph_edge *cs,
3984 struct cgraph_node *node,
3985 vec<cgraph_edge *> *new_edges)
3987 class ipa_edge_args *top;
3988 struct cgraph_edge *ie, *next_ie, *new_direct_edge;
3989 struct cgraph_node *new_root;
3990 class ipa_node_params *new_root_info, *inlined_node_info;
3991 bool res = false;
3993 ipa_check_create_edge_args ();
3994 top = ipa_edge_args_sum->get (cs);
3995 new_root = cs->caller->inlined_to
3996 ? cs->caller->inlined_to : cs->caller;
3997 new_root_info = ipa_node_params_sum->get (new_root);
3998 inlined_node_info = ipa_node_params_sum->get (cs->callee->function_symbol ());
4000 for (ie = node->indirect_calls; ie; ie = next_ie)
4002 class cgraph_indirect_call_info *ici = ie->indirect_info;
4003 struct ipa_jump_func *jfunc;
4004 int param_index;
4006 next_ie = ie->next_callee;
4008 if (ici->param_index == -1)
4009 continue;
4011 /* We must check range due to calls with variable number of arguments: */
4012 if (!top || ici->param_index >= ipa_get_cs_argument_count (top))
4014 ici->param_index = -1;
4015 continue;
4018 param_index = ici->param_index;
4019 jfunc = ipa_get_ith_jump_func (top, param_index);
4021 auto_vec<cgraph_node *, 4> spec_targets;
4022 if (ie->speculative)
4023 for (cgraph_edge *direct = ie->first_speculative_call_target ();
4024 direct;
4025 direct = direct->next_speculative_call_target ())
4026 spec_targets.safe_push (direct->callee);
4028 if (!opt_for_fn (node->decl, flag_indirect_inlining))
4029 new_direct_edge = NULL;
4030 else if (ici->polymorphic)
4032 ipa_polymorphic_call_context ctx;
4033 ctx = ipa_context_from_jfunc (new_root_info, cs, param_index, jfunc);
4034 new_direct_edge = try_make_edge_direct_virtual_call (ie, jfunc, ctx,
4035 new_root,
4036 new_root_info);
4038 else
4040 tree target_type = ipa_get_type (inlined_node_info, param_index);
4041 new_direct_edge = try_make_edge_direct_simple_call (ie, jfunc,
4042 target_type,
4043 new_root,
4044 new_root_info);
4047 /* If speculation was removed, then we need to do nothing. */
4048 if (new_direct_edge && new_direct_edge != ie
4049 && spec_targets.contains (new_direct_edge->callee))
4051 new_direct_edge->indirect_inlining_edge = 1;
4052 res = true;
4053 if (!new_direct_edge->speculative)
4054 continue;
4056 else if (new_direct_edge)
4058 new_direct_edge->indirect_inlining_edge = 1;
4059 if (new_edges)
4061 new_edges->safe_push (new_direct_edge);
4062 res = true;
4064 /* If speculative edge was introduced we still need to update
4065 call info of the indirect edge. */
4066 if (!new_direct_edge->speculative)
4067 continue;
4069 if (jfunc->type == IPA_JF_PASS_THROUGH
4070 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
4072 if (ici->agg_contents
4073 && !ipa_get_jf_pass_through_agg_preserved (jfunc)
4074 && !ici->polymorphic)
4075 ici->param_index = -1;
4076 else
4078 ici->param_index = ipa_get_jf_pass_through_formal_id (jfunc);
4079 if (ici->polymorphic
4080 && !ipa_get_jf_pass_through_type_preserved (jfunc))
4081 ici->vptr_changed = true;
4082 ipa_set_param_used_by_indirect_call (new_root_info,
4083 ici->param_index, true);
4084 if (ici->polymorphic)
4085 ipa_set_param_used_by_polymorphic_call (new_root_info,
4086 ici->param_index, true);
4089 else if (jfunc->type == IPA_JF_ANCESTOR)
4091 if (ici->agg_contents
4092 && !ipa_get_jf_ancestor_agg_preserved (jfunc)
4093 && !ici->polymorphic)
4094 ici->param_index = -1;
4095 else
4097 ici->param_index = ipa_get_jf_ancestor_formal_id (jfunc);
4098 ici->offset += ipa_get_jf_ancestor_offset (jfunc);
4099 if (ici->polymorphic
4100 && !ipa_get_jf_ancestor_type_preserved (jfunc))
4101 ici->vptr_changed = true;
4102 ipa_set_param_used_by_indirect_call (new_root_info,
4103 ici->param_index, true);
4104 if (ici->polymorphic)
4105 ipa_set_param_used_by_polymorphic_call (new_root_info,
4106 ici->param_index, true);
4109 else
4110 /* Either we can find a destination for this edge now or never. */
4111 ici->param_index = -1;
4114 return res;
4117 /* Recursively traverse subtree of NODE (including node) made of inlined
4118 cgraph_edges when CS has been inlined and invoke
4119 update_indirect_edges_after_inlining on all nodes and
4120 update_jump_functions_after_inlining on all non-inlined edges that lead out
4121 of this subtree. Newly discovered indirect edges will be added to
4122 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were
4123 created. */
4125 static bool
4126 propagate_info_to_inlined_callees (struct cgraph_edge *cs,
4127 struct cgraph_node *node,
4128 vec<cgraph_edge *> *new_edges)
4130 struct cgraph_edge *e;
4131 bool res;
4133 res = update_indirect_edges_after_inlining (cs, node, new_edges);
4135 for (e = node->callees; e; e = e->next_callee)
4136 if (!e->inline_failed)
4137 res |= propagate_info_to_inlined_callees (cs, e->callee, new_edges);
4138 else
4139 update_jump_functions_after_inlining (cs, e);
4140 for (e = node->indirect_calls; e; e = e->next_callee)
4141 update_jump_functions_after_inlining (cs, e);
4143 return res;
4146 /* Combine two controlled uses counts as done during inlining. */
4148 static int
4149 combine_controlled_uses_counters (int c, int d)
4151 if (c == IPA_UNDESCRIBED_USE || d == IPA_UNDESCRIBED_USE)
4152 return IPA_UNDESCRIBED_USE;
4153 else
4154 return c + d - 1;
4157 /* Propagate number of controlled users from CS->caleee to the new root of the
4158 tree of inlined nodes. */
4160 static void
4161 propagate_controlled_uses (struct cgraph_edge *cs)
4163 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
4164 if (!args)
4165 return;
4166 struct cgraph_node *new_root = cs->caller->inlined_to
4167 ? cs->caller->inlined_to : cs->caller;
4168 ipa_node_params *new_root_info = ipa_node_params_sum->get (new_root);
4169 ipa_node_params *old_root_info = ipa_node_params_sum->get (cs->callee);
4170 int count, i;
4172 if (!old_root_info)
4173 return;
4175 count = MIN (ipa_get_cs_argument_count (args),
4176 ipa_get_param_count (old_root_info));
4177 for (i = 0; i < count; i++)
4179 struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
4180 struct ipa_cst_ref_desc *rdesc;
4182 if (jf->type == IPA_JF_PASS_THROUGH
4183 && !ipa_get_jf_pass_through_refdesc_decremented (jf))
4185 int src_idx, c, d;
4186 src_idx = ipa_get_jf_pass_through_formal_id (jf);
4187 c = ipa_get_controlled_uses (new_root_info, src_idx);
4188 d = ipa_get_controlled_uses (old_root_info, i);
4190 gcc_checking_assert (ipa_get_jf_pass_through_operation (jf)
4191 == NOP_EXPR || c == IPA_UNDESCRIBED_USE);
4192 c = combine_controlled_uses_counters (c, d);
4193 ipa_set_controlled_uses (new_root_info, src_idx, c);
4194 bool lderef = true;
4195 if (c != IPA_UNDESCRIBED_USE)
4197 lderef = (ipa_get_param_load_dereferenced (new_root_info, src_idx)
4198 || ipa_get_param_load_dereferenced (old_root_info, i));
4199 ipa_set_param_load_dereferenced (new_root_info, src_idx, lderef);
4202 if (c == 0 && !lderef && new_root_info->ipcp_orig_node)
4204 struct cgraph_node *n;
4205 struct ipa_ref *ref;
4206 tree t = new_root_info->known_csts[src_idx];
4208 if (t && TREE_CODE (t) == ADDR_EXPR
4209 && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
4210 && (n = cgraph_node::get (TREE_OPERAND (t, 0)))
4211 && (ref = new_root->find_reference (n, NULL, 0,
4212 IPA_REF_ADDR)))
4214 if (dump_file)
4215 fprintf (dump_file, "ipa-prop: Removing cloning-created "
4216 "reference from %s to %s.\n",
4217 new_root->dump_name (),
4218 n->dump_name ());
4219 ref->remove_reference ();
4223 else if (jf->type == IPA_JF_CONST
4224 && (rdesc = jfunc_rdesc_usable (jf)))
4226 int d = ipa_get_controlled_uses (old_root_info, i);
4227 int c = rdesc->refcount;
4228 tree cst = ipa_get_jf_constant (jf);
4229 rdesc->refcount = combine_controlled_uses_counters (c, d);
4230 if (rdesc->refcount != IPA_UNDESCRIBED_USE
4231 && ipa_get_param_load_dereferenced (old_root_info, i)
4232 && TREE_CODE (cst) == ADDR_EXPR
4233 && VAR_P (TREE_OPERAND (cst, 0)))
4235 symtab_node *n = symtab_node::get (TREE_OPERAND (cst, 0));
4236 new_root->create_reference (n, IPA_REF_LOAD, NULL);
4237 if (dump_file)
4238 fprintf (dump_file, "ipa-prop: Address IPA constant will reach "
4239 "a load so adding LOAD reference from %s to %s.\n",
4240 new_root->dump_name (), n->dump_name ());
4242 if (rdesc->refcount == 0)
4244 gcc_checking_assert (TREE_CODE (cst) == ADDR_EXPR
4245 && ((TREE_CODE (TREE_OPERAND (cst, 0))
4246 == FUNCTION_DECL)
4247 || VAR_P (TREE_OPERAND (cst, 0))));
4249 symtab_node *n = symtab_node::get (TREE_OPERAND (cst, 0));
4250 if (n)
4252 remove_described_reference (n, rdesc);
4253 cgraph_node *clone = cs->caller;
4254 while (clone->inlined_to
4255 && clone->ipcp_clone
4256 && clone != rdesc->cs->caller)
4258 struct ipa_ref *ref;
4259 ref = clone->find_reference (n, NULL, 0, IPA_REF_ADDR);
4260 if (ref)
4262 if (dump_file)
4263 fprintf (dump_file, "ipa-prop: Removing "
4264 "cloning-created reference "
4265 "from %s to %s.\n",
4266 clone->dump_name (),
4267 n->dump_name ());
4268 ref->remove_reference ();
4270 clone = clone->callers->caller;
4277 for (i = ipa_get_param_count (old_root_info);
4278 i < ipa_get_cs_argument_count (args);
4279 i++)
4281 struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
4283 if (jf->type == IPA_JF_CONST)
4285 struct ipa_cst_ref_desc *rdesc = jfunc_rdesc_usable (jf);
4286 if (rdesc)
4287 rdesc->refcount = IPA_UNDESCRIBED_USE;
4289 else if (jf->type == IPA_JF_PASS_THROUGH)
4290 ipa_set_controlled_uses (new_root_info,
4291 jf->value.pass_through.formal_id,
4292 IPA_UNDESCRIBED_USE);
4296 /* Update jump functions and call note functions on inlining the call site CS.
4297 CS is expected to lead to a node already cloned by
4298 cgraph_clone_inline_nodes. Newly discovered indirect edges will be added to
4299 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were +
4300 created. */
4302 bool
4303 ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
4304 vec<cgraph_edge *> *new_edges)
4306 bool changed;
4307 /* Do nothing if the preparation phase has not been carried out yet
4308 (i.e. during early inlining). */
4309 if (!ipa_node_params_sum)
4310 return false;
4311 gcc_assert (ipa_edge_args_sum);
4313 propagate_controlled_uses (cs);
4314 changed = propagate_info_to_inlined_callees (cs, cs->callee, new_edges);
4315 ipa_node_params_sum->remove (cs->callee);
4317 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
4318 if (args)
4320 bool ok = true;
4321 if (args->jump_functions)
4323 struct ipa_jump_func *jf;
4324 int i;
4325 FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
4326 if (jf->type == IPA_JF_CONST
4327 && ipa_get_jf_constant_rdesc (jf))
4329 ok = false;
4330 break;
4333 if (ok)
4334 ipa_edge_args_sum->remove (cs);
4336 if (ipcp_transformation_sum)
4337 ipcp_transformation_sum->remove (cs->callee);
4339 return changed;
4342 /* Ensure that array of edge arguments infos is big enough to accommodate a
4343 structure for all edges and reallocates it if not. Also, allocate
4344 associated hash tables is they do not already exist. */
4346 void
4347 ipa_check_create_edge_args (void)
4349 if (!ipa_edge_args_sum)
4350 ipa_edge_args_sum
4351 = (new (ggc_alloc_no_dtor<ipa_edge_args_sum_t> ())
4352 ipa_edge_args_sum_t (symtab, true));
4353 if (!ipa_vr_hash_table)
4354 ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
4357 /* Free all ipa_edge structures. */
4359 void
4360 ipa_free_all_edge_args (void)
4362 if (!ipa_edge_args_sum)
4363 return;
4365 ggc_delete (ipa_edge_args_sum);
4366 ipa_edge_args_sum = NULL;
4369 /* Free all ipa_node_params structures. */
4371 void
4372 ipa_free_all_node_params (void)
4374 if (ipa_node_params_sum)
4375 ggc_delete (ipa_node_params_sum);
4376 ipa_node_params_sum = NULL;
4379 /* Initialize IPA CP transformation summary and also allocate any necessary hash
4380 tables if they do not already exist. */
4382 void
4383 ipcp_transformation_initialize (void)
4385 if (!ipa_vr_hash_table)
4386 ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
4387 if (ipcp_transformation_sum == NULL)
4389 ipcp_transformation_sum = ipcp_transformation_t::create_ggc (symtab);
4390 ipcp_transformation_sum->disable_insertion_hook ();
4394 /* Release the IPA CP transformation summary. */
4396 void
4397 ipcp_free_transformation_sum (void)
4399 if (!ipcp_transformation_sum)
4400 return;
4402 ipcp_transformation_sum->~function_summary<ipcp_transformation *> ();
4403 ggc_free (ipcp_transformation_sum);
4404 ipcp_transformation_sum = NULL;
4407 /* Set the aggregate replacements of NODE to be AGGVALS. */
4409 void
4410 ipa_set_node_agg_value_chain (struct cgraph_node *node,
4411 vec<ipa_argagg_value, va_gc> *aggs)
4413 ipcp_transformation_initialize ();
4414 ipcp_transformation *s = ipcp_transformation_sum->get_create (node);
4415 s->m_agg_values = aggs;
4418 /* Hook that is called by cgraph.cc when an edge is removed. Adjust reference
4419 count data structures accordingly. */
4421 void
4422 ipa_edge_args_sum_t::remove (cgraph_edge *cs, ipa_edge_args *args)
4424 if (args->jump_functions)
4426 struct ipa_jump_func *jf;
4427 int i;
4428 FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
4430 struct ipa_cst_ref_desc *rdesc;
4431 try_decrement_rdesc_refcount (jf);
4432 if (jf->type == IPA_JF_CONST
4433 && (rdesc = ipa_get_jf_constant_rdesc (jf))
4434 && rdesc->cs == cs)
4435 rdesc->cs = NULL;
4440 /* Method invoked when an edge is duplicated. Copy ipa_edge_args and adjust
4441 reference count data strucutres accordingly. */
4443 void
4444 ipa_edge_args_sum_t::duplicate (cgraph_edge *src, cgraph_edge *dst,
4445 ipa_edge_args *old_args, ipa_edge_args *new_args)
4447 unsigned int i;
4449 new_args->jump_functions = vec_safe_copy (old_args->jump_functions);
4450 if (old_args->polymorphic_call_contexts)
4451 new_args->polymorphic_call_contexts
4452 = vec_safe_copy (old_args->polymorphic_call_contexts);
4454 for (i = 0; i < vec_safe_length (old_args->jump_functions); i++)
4456 struct ipa_jump_func *src_jf = ipa_get_ith_jump_func (old_args, i);
4457 struct ipa_jump_func *dst_jf = ipa_get_ith_jump_func (new_args, i);
4459 dst_jf->agg.items = vec_safe_copy (dst_jf->agg.items);
4461 if (src_jf->type == IPA_JF_CONST)
4463 struct ipa_cst_ref_desc *src_rdesc = jfunc_rdesc_usable (src_jf);
4465 if (!src_rdesc)
4466 dst_jf->value.constant.rdesc = NULL;
4467 else if (src->caller == dst->caller)
4469 /* Creation of a speculative edge. If the source edge is the one
4470 grabbing a reference, we must create a new (duplicate)
4471 reference description. Otherwise they refer to the same
4472 description corresponding to a reference taken in a function
4473 src->caller is inlined to. In that case we just must
4474 increment the refcount. */
4475 if (src_rdesc->cs == src)
4477 symtab_node *n = symtab_node_for_jfunc (src_jf);
4478 gcc_checking_assert (n);
4479 ipa_ref *ref
4480 = src->caller->find_reference (n, src->call_stmt,
4481 src->lto_stmt_uid,
4482 IPA_REF_ADDR);
4483 gcc_checking_assert (ref);
4484 dst->caller->clone_reference (ref, ref->stmt);
4486 ipa_cst_ref_desc *dst_rdesc = ipa_refdesc_pool.allocate ();
4487 dst_rdesc->cs = dst;
4488 dst_rdesc->refcount = src_rdesc->refcount;
4489 dst_rdesc->next_duplicate = NULL;
4490 dst_jf->value.constant.rdesc = dst_rdesc;
4492 else
4494 src_rdesc->refcount++;
4495 dst_jf->value.constant.rdesc = src_rdesc;
4498 else if (src_rdesc->cs == src)
4500 struct ipa_cst_ref_desc *dst_rdesc = ipa_refdesc_pool.allocate ();
4501 dst_rdesc->cs = dst;
4502 dst_rdesc->refcount = src_rdesc->refcount;
4503 dst_rdesc->next_duplicate = src_rdesc->next_duplicate;
4504 src_rdesc->next_duplicate = dst_rdesc;
4505 dst_jf->value.constant.rdesc = dst_rdesc;
4507 else
4509 struct ipa_cst_ref_desc *dst_rdesc;
4510 /* This can happen during inlining, when a JFUNC can refer to a
4511 reference taken in a function up in the tree of inline clones.
4512 We need to find the duplicate that refers to our tree of
4513 inline clones. */
4515 gcc_assert (dst->caller->inlined_to);
4516 for (dst_rdesc = src_rdesc->next_duplicate;
4517 dst_rdesc;
4518 dst_rdesc = dst_rdesc->next_duplicate)
4520 struct cgraph_node *top;
4521 top = dst_rdesc->cs->caller->inlined_to
4522 ? dst_rdesc->cs->caller->inlined_to
4523 : dst_rdesc->cs->caller;
4524 if (dst->caller->inlined_to == top)
4525 break;
4527 gcc_assert (dst_rdesc);
4528 dst_jf->value.constant.rdesc = dst_rdesc;
4531 else if (dst_jf->type == IPA_JF_PASS_THROUGH
4532 && src->caller == dst->caller)
4534 struct cgraph_node *inline_root = dst->caller->inlined_to
4535 ? dst->caller->inlined_to : dst->caller;
4536 ipa_node_params *root_info = ipa_node_params_sum->get (inline_root);
4537 int idx = ipa_get_jf_pass_through_formal_id (dst_jf);
4539 int c = ipa_get_controlled_uses (root_info, idx);
4540 if (c != IPA_UNDESCRIBED_USE)
4542 c++;
4543 ipa_set_controlled_uses (root_info, idx, c);
4549 /* Analyze newly added function into callgraph. */
4551 static void
4552 ipa_add_new_function (cgraph_node *node, void *data ATTRIBUTE_UNUSED)
4554 if (node->has_gimple_body_p ())
4555 ipa_analyze_node (node);
4558 /* Hook that is called by summary when a node is duplicated. */
4560 void
4561 ipa_node_params_t::duplicate(cgraph_node *, cgraph_node *,
4562 ipa_node_params *old_info,
4563 ipa_node_params *new_info)
4565 new_info->descriptors = vec_safe_copy (old_info->descriptors);
4566 gcc_assert (new_info->lattices.is_empty ());
4567 new_info->ipcp_orig_node = old_info->ipcp_orig_node;
4568 new_info->known_csts = old_info->known_csts.copy ();
4569 new_info->known_contexts = old_info->known_contexts.copy ();
4571 new_info->analysis_done = old_info->analysis_done;
4572 new_info->node_enqueued = old_info->node_enqueued;
4573 new_info->versionable = old_info->versionable;
4576 /* Duplication of ipcp transformation summaries. */
4578 void
4579 ipcp_transformation_t::duplicate(cgraph_node *, cgraph_node *dst,
4580 ipcp_transformation *src_trans,
4581 ipcp_transformation *dst_trans)
4583 /* Avoid redundant work of duplicating vectors we will never use. */
4584 if (dst->inlined_to)
4585 return;
4586 dst_trans->m_agg_values = vec_safe_copy (src_trans->m_agg_values);
4587 dst_trans->m_vr = vec_safe_copy (src_trans->m_vr);
4590 /* Register our cgraph hooks if they are not already there. */
4592 void
4593 ipa_register_cgraph_hooks (void)
4595 ipa_check_create_node_params ();
4596 ipa_check_create_edge_args ();
4598 function_insertion_hook_holder =
4599 symtab->add_cgraph_insertion_hook (&ipa_add_new_function, NULL);
4602 /* Unregister our cgraph hooks if they are not already there. */
4604 static void
4605 ipa_unregister_cgraph_hooks (void)
4607 if (function_insertion_hook_holder)
4608 symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
4609 function_insertion_hook_holder = NULL;
4612 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
4613 longer needed after ipa-cp. */
4615 void
4616 ipa_free_all_structures_after_ipa_cp (void)
4618 if (!optimize && !in_lto_p)
4620 ipa_free_all_edge_args ();
4621 ipa_free_all_node_params ();
4622 ipcp_sources_pool.release ();
4623 ipcp_cst_values_pool.release ();
4624 ipcp_poly_ctx_values_pool.release ();
4625 ipcp_agg_lattice_pool.release ();
4626 ipa_unregister_cgraph_hooks ();
4627 ipa_refdesc_pool.release ();
4631 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
4632 longer needed after indirect inlining. */
4634 void
4635 ipa_free_all_structures_after_iinln (void)
4637 ipa_free_all_edge_args ();
4638 ipa_free_all_node_params ();
4639 ipa_unregister_cgraph_hooks ();
4640 ipcp_sources_pool.release ();
4641 ipcp_cst_values_pool.release ();
4642 ipcp_poly_ctx_values_pool.release ();
4643 ipcp_agg_lattice_pool.release ();
4644 ipa_refdesc_pool.release ();
4647 /* Print ipa_tree_map data structures of all functions in the
4648 callgraph to F. */
4650 void
4651 ipa_print_node_params (FILE *f, struct cgraph_node *node)
4653 int i, count;
4654 class ipa_node_params *info;
4656 if (!node->definition)
4657 return;
4658 info = ipa_node_params_sum->get (node);
4659 fprintf (f, " function %s parameter descriptors:\n", node->dump_name ());
4660 if (!info)
4662 fprintf (f, " no params return\n");
4663 return;
4665 count = ipa_get_param_count (info);
4666 for (i = 0; i < count; i++)
4668 int c;
4670 fprintf (f, " ");
4671 ipa_dump_param (f, info, i);
4672 if (ipa_is_param_used (info, i))
4673 fprintf (f, " used");
4674 if (ipa_is_param_used_by_ipa_predicates (info, i))
4675 fprintf (f, " used_by_ipa_predicates");
4676 if (ipa_is_param_used_by_indirect_call (info, i))
4677 fprintf (f, " used_by_indirect_call");
4678 if (ipa_is_param_used_by_polymorphic_call (info, i))
4679 fprintf (f, " used_by_polymorphic_call");
4680 c = ipa_get_controlled_uses (info, i);
4681 if (c == IPA_UNDESCRIBED_USE)
4682 fprintf (f, " undescribed_use");
4683 else
4684 fprintf (f, " controlled_uses=%i %s", c,
4685 ipa_get_param_load_dereferenced (info, i)
4686 ? "(load_dereferenced)" : "");
4687 fprintf (f, "\n");
4691 /* Print ipa_tree_map data structures of all functions in the
4692 callgraph to F. */
4694 void
4695 ipa_print_all_params (FILE * f)
4697 struct cgraph_node *node;
4699 fprintf (f, "\nFunction parameters:\n");
4700 FOR_EACH_FUNCTION (node)
4701 ipa_print_node_params (f, node);
4704 /* Stream out jump function JUMP_FUNC to OB. */
4706 static void
4707 ipa_write_jump_function (struct output_block *ob,
4708 struct ipa_jump_func *jump_func)
4710 struct ipa_agg_jf_item *item;
4711 struct bitpack_d bp;
4712 int i, count;
4713 int flag = 0;
4715 /* ADDR_EXPRs are very comon IP invariants; save some streamer data
4716 as well as WPA memory by handling them specially. */
4717 if (jump_func->type == IPA_JF_CONST
4718 && TREE_CODE (jump_func->value.constant.value) == ADDR_EXPR)
4719 flag = 1;
4721 streamer_write_uhwi (ob, jump_func->type * 2 + flag);
4722 switch (jump_func->type)
4724 case IPA_JF_UNKNOWN:
4725 break;
4726 case IPA_JF_CONST:
4727 gcc_assert (
4728 EXPR_LOCATION (jump_func->value.constant.value) == UNKNOWN_LOCATION);
4729 stream_write_tree (ob,
4730 flag
4731 ? TREE_OPERAND (jump_func->value.constant.value, 0)
4732 : jump_func->value.constant.value, true);
4733 break;
4734 case IPA_JF_PASS_THROUGH:
4735 streamer_write_uhwi (ob, jump_func->value.pass_through.operation);
4736 if (jump_func->value.pass_through.operation == NOP_EXPR)
4738 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4739 bp = bitpack_create (ob->main_stream);
4740 bp_pack_value (&bp, jump_func->value.pass_through.agg_preserved, 1);
4741 gcc_assert (!jump_func->value.pass_through.refdesc_decremented);
4742 streamer_write_bitpack (&bp);
4744 else if (TREE_CODE_CLASS (jump_func->value.pass_through.operation)
4745 == tcc_unary)
4746 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4747 else
4749 stream_write_tree (ob, jump_func->value.pass_through.operand, true);
4750 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4752 break;
4753 case IPA_JF_ANCESTOR:
4754 streamer_write_uhwi (ob, jump_func->value.ancestor.offset);
4755 streamer_write_uhwi (ob, jump_func->value.ancestor.formal_id);
4756 bp = bitpack_create (ob->main_stream);
4757 bp_pack_value (&bp, jump_func->value.ancestor.agg_preserved, 1);
4758 bp_pack_value (&bp, jump_func->value.ancestor.keep_null, 1);
4759 streamer_write_bitpack (&bp);
4760 break;
4761 default:
4762 fatal_error (UNKNOWN_LOCATION, "invalid jump function in LTO stream");
4765 count = vec_safe_length (jump_func->agg.items);
4766 streamer_write_uhwi (ob, count);
4767 if (count)
4769 bp = bitpack_create (ob->main_stream);
4770 bp_pack_value (&bp, jump_func->agg.by_ref, 1);
4771 streamer_write_bitpack (&bp);
4774 FOR_EACH_VEC_SAFE_ELT (jump_func->agg.items, i, item)
4776 stream_write_tree (ob, item->type, true);
4777 streamer_write_uhwi (ob, item->offset);
4778 streamer_write_uhwi (ob, item->jftype);
4779 switch (item->jftype)
4781 case IPA_JF_UNKNOWN:
4782 break;
4783 case IPA_JF_CONST:
4784 stream_write_tree (ob, item->value.constant, true);
4785 break;
4786 case IPA_JF_PASS_THROUGH:
4787 case IPA_JF_LOAD_AGG:
4788 streamer_write_uhwi (ob, item->value.pass_through.operation);
4789 streamer_write_uhwi (ob, item->value.pass_through.formal_id);
4790 if (TREE_CODE_CLASS (item->value.pass_through.operation)
4791 != tcc_unary)
4792 stream_write_tree (ob, item->value.pass_through.operand, true);
4793 if (item->jftype == IPA_JF_LOAD_AGG)
4795 stream_write_tree (ob, item->value.load_agg.type, true);
4796 streamer_write_uhwi (ob, item->value.load_agg.offset);
4797 bp = bitpack_create (ob->main_stream);
4798 bp_pack_value (&bp, item->value.load_agg.by_ref, 1);
4799 streamer_write_bitpack (&bp);
4801 break;
4802 default:
4803 fatal_error (UNKNOWN_LOCATION,
4804 "invalid jump function in LTO stream");
4808 bp = bitpack_create (ob->main_stream);
4809 if (jump_func->m_vr)
4810 jump_func->m_vr->streamer_write (ob);
4811 else
4813 bp_pack_value (&bp, false, 1);
4814 streamer_write_bitpack (&bp);
4818 /* Read in jump function JUMP_FUNC from IB. */
4820 static void
4821 ipa_read_jump_function (class lto_input_block *ib,
4822 struct ipa_jump_func *jump_func,
4823 struct cgraph_edge *cs,
4824 class data_in *data_in,
4825 bool prevails)
4827 enum jump_func_type jftype;
4828 enum tree_code operation;
4829 int i, count;
4830 int val = streamer_read_uhwi (ib);
4831 bool flag = val & 1;
4833 jftype = (enum jump_func_type) (val / 2);
4834 switch (jftype)
4836 case IPA_JF_UNKNOWN:
4837 ipa_set_jf_unknown (jump_func);
4838 break;
4839 case IPA_JF_CONST:
4841 tree t = stream_read_tree (ib, data_in);
4842 if (flag && prevails)
4843 t = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
4844 ipa_set_jf_constant (jump_func, t, cs);
4846 break;
4847 case IPA_JF_PASS_THROUGH:
4848 operation = (enum tree_code) streamer_read_uhwi (ib);
4849 if (operation == NOP_EXPR)
4851 int formal_id = streamer_read_uhwi (ib);
4852 struct bitpack_d bp = streamer_read_bitpack (ib);
4853 bool agg_preserved = bp_unpack_value (&bp, 1);
4854 ipa_set_jf_simple_pass_through (jump_func, formal_id, agg_preserved);
4856 else if (TREE_CODE_CLASS (operation) == tcc_unary)
4858 int formal_id = streamer_read_uhwi (ib);
4859 ipa_set_jf_unary_pass_through (jump_func, formal_id, operation);
4861 else
4863 tree operand = stream_read_tree (ib, data_in);
4864 int formal_id = streamer_read_uhwi (ib);
4865 ipa_set_jf_arith_pass_through (jump_func, formal_id, operand,
4866 operation);
4868 break;
4869 case IPA_JF_ANCESTOR:
4871 HOST_WIDE_INT offset = streamer_read_uhwi (ib);
4872 int formal_id = streamer_read_uhwi (ib);
4873 struct bitpack_d bp = streamer_read_bitpack (ib);
4874 bool agg_preserved = bp_unpack_value (&bp, 1);
4875 bool keep_null = bp_unpack_value (&bp, 1);
4876 ipa_set_ancestor_jf (jump_func, offset, formal_id, agg_preserved,
4877 keep_null);
4878 break;
4880 default:
4881 fatal_error (UNKNOWN_LOCATION, "invalid jump function in LTO stream");
4884 count = streamer_read_uhwi (ib);
4885 if (prevails)
4887 jump_func->agg.items = NULL;
4888 vec_safe_reserve (jump_func->agg.items, count, true);
4890 if (count)
4892 struct bitpack_d bp = streamer_read_bitpack (ib);
4893 jump_func->agg.by_ref = bp_unpack_value (&bp, 1);
4895 for (i = 0; i < count; i++)
4897 struct ipa_agg_jf_item item;
4898 item.type = stream_read_tree (ib, data_in);
4899 item.offset = streamer_read_uhwi (ib);
4900 item.jftype = (enum jump_func_type) streamer_read_uhwi (ib);
4902 switch (item.jftype)
4904 case IPA_JF_UNKNOWN:
4905 break;
4906 case IPA_JF_CONST:
4907 item.value.constant = stream_read_tree (ib, data_in);
4908 break;
4909 case IPA_JF_PASS_THROUGH:
4910 case IPA_JF_LOAD_AGG:
4911 operation = (enum tree_code) streamer_read_uhwi (ib);
4912 item.value.pass_through.operation = operation;
4913 item.value.pass_through.formal_id = streamer_read_uhwi (ib);
4914 if (TREE_CODE_CLASS (operation) == tcc_unary)
4915 item.value.pass_through.operand = NULL_TREE;
4916 else
4917 item.value.pass_through.operand = stream_read_tree (ib, data_in);
4918 if (item.jftype == IPA_JF_LOAD_AGG)
4920 struct bitpack_d bp;
4921 item.value.load_agg.type = stream_read_tree (ib, data_in);
4922 item.value.load_agg.offset = streamer_read_uhwi (ib);
4923 bp = streamer_read_bitpack (ib);
4924 item.value.load_agg.by_ref = bp_unpack_value (&bp, 1);
4926 break;
4927 default:
4928 fatal_error (UNKNOWN_LOCATION,
4929 "invalid jump function in LTO stream");
4931 if (prevails)
4932 jump_func->agg.items->quick_push (item);
4935 ipa_vr vr;
4936 vr.streamer_read (ib, data_in);
4937 if (vr.known_p ())
4939 if (prevails)
4940 ipa_set_jfunc_vr (jump_func, vr);
4942 else
4943 jump_func->m_vr = NULL;
4946 /* Stream out parts of cgraph_indirect_call_info corresponding to CS that are
4947 relevant to indirect inlining to OB. */
4949 static void
4950 ipa_write_indirect_edge_info (struct output_block *ob,
4951 struct cgraph_edge *cs)
4953 class cgraph_indirect_call_info *ii = cs->indirect_info;
4954 struct bitpack_d bp;
4956 streamer_write_hwi (ob, ii->param_index);
4957 bp = bitpack_create (ob->main_stream);
4958 bp_pack_value (&bp, ii->polymorphic, 1);
4959 bp_pack_value (&bp, ii->agg_contents, 1);
4960 bp_pack_value (&bp, ii->member_ptr, 1);
4961 bp_pack_value (&bp, ii->by_ref, 1);
4962 bp_pack_value (&bp, ii->guaranteed_unmodified, 1);
4963 bp_pack_value (&bp, ii->vptr_changed, 1);
4964 streamer_write_bitpack (&bp);
4965 if (ii->agg_contents || ii->polymorphic)
4966 streamer_write_hwi (ob, ii->offset);
4967 else
4968 gcc_assert (ii->offset == 0);
4970 if (ii->polymorphic)
4972 streamer_write_hwi (ob, ii->otr_token);
4973 stream_write_tree (ob, ii->otr_type, true);
4974 ii->context.stream_out (ob);
4978 /* Read in parts of cgraph_indirect_call_info corresponding to CS that are
4979 relevant to indirect inlining from IB. */
4981 static void
4982 ipa_read_indirect_edge_info (class lto_input_block *ib,
4983 class data_in *data_in,
4984 struct cgraph_edge *cs,
4985 class ipa_node_params *info)
4987 class cgraph_indirect_call_info *ii = cs->indirect_info;
4988 struct bitpack_d bp;
4990 ii->param_index = (int) streamer_read_hwi (ib);
4991 bp = streamer_read_bitpack (ib);
4992 ii->polymorphic = bp_unpack_value (&bp, 1);
4993 ii->agg_contents = bp_unpack_value (&bp, 1);
4994 ii->member_ptr = bp_unpack_value (&bp, 1);
4995 ii->by_ref = bp_unpack_value (&bp, 1);
4996 ii->guaranteed_unmodified = bp_unpack_value (&bp, 1);
4997 ii->vptr_changed = bp_unpack_value (&bp, 1);
4998 if (ii->agg_contents || ii->polymorphic)
4999 ii->offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
5000 else
5001 ii->offset = 0;
5002 if (ii->polymorphic)
5004 ii->otr_token = (HOST_WIDE_INT) streamer_read_hwi (ib);
5005 ii->otr_type = stream_read_tree (ib, data_in);
5006 ii->context.stream_in (ib, data_in);
5008 if (info && ii->param_index >= 0)
5010 if (ii->polymorphic)
5011 ipa_set_param_used_by_polymorphic_call (info,
5012 ii->param_index , true);
5013 ipa_set_param_used_by_indirect_call (info,
5014 ii->param_index, true);
5018 /* Stream out NODE info to OB. */
5020 static void
5021 ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
5023 int node_ref;
5024 lto_symtab_encoder_t encoder;
5025 ipa_node_params *info = ipa_node_params_sum->get (node);
5026 int j;
5027 struct cgraph_edge *e;
5028 struct bitpack_d bp;
5030 encoder = ob->decl_state->symtab_node_encoder;
5031 node_ref = lto_symtab_encoder_encode (encoder, node);
5032 streamer_write_uhwi (ob, node_ref);
5034 streamer_write_uhwi (ob, ipa_get_param_count (info));
5035 for (j = 0; j < ipa_get_param_count (info); j++)
5036 streamer_write_uhwi (ob, ipa_get_param_move_cost (info, j));
5037 bp = bitpack_create (ob->main_stream);
5038 gcc_assert (info->analysis_done
5039 || ipa_get_param_count (info) == 0);
5040 gcc_assert (!info->node_enqueued);
5041 gcc_assert (!info->ipcp_orig_node);
5042 for (j = 0; j < ipa_get_param_count (info); j++)
5044 /* TODO: We could just not stream the bit in the undescribed case. */
5045 bool d = (ipa_get_controlled_uses (info, j) != IPA_UNDESCRIBED_USE)
5046 ? ipa_get_param_load_dereferenced (info, j) : true;
5047 bp_pack_value (&bp, d, 1);
5048 bp_pack_value (&bp, ipa_is_param_used (info, j), 1);
5050 streamer_write_bitpack (&bp);
5051 for (j = 0; j < ipa_get_param_count (info); j++)
5053 streamer_write_hwi (ob, ipa_get_controlled_uses (info, j));
5054 stream_write_tree (ob, ipa_get_type (info, j), true);
5056 for (e = node->callees; e; e = e->next_callee)
5058 ipa_edge_args *args = ipa_edge_args_sum->get (e);
5060 if (!args)
5062 streamer_write_uhwi (ob, 0);
5063 continue;
5066 streamer_write_uhwi (ob,
5067 ipa_get_cs_argument_count (args) * 2
5068 + (args->polymorphic_call_contexts != NULL));
5069 for (j = 0; j < ipa_get_cs_argument_count (args); j++)
5071 ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
5072 if (args->polymorphic_call_contexts != NULL)
5073 ipa_get_ith_polymorhic_call_context (args, j)->stream_out (ob);
5076 for (e = node->indirect_calls; e; e = e->next_callee)
5078 ipa_edge_args *args = ipa_edge_args_sum->get (e);
5079 if (!args)
5080 streamer_write_uhwi (ob, 0);
5081 else
5083 streamer_write_uhwi (ob,
5084 ipa_get_cs_argument_count (args) * 2
5085 + (args->polymorphic_call_contexts != NULL));
5086 for (j = 0; j < ipa_get_cs_argument_count (args); j++)
5088 ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
5089 if (args->polymorphic_call_contexts != NULL)
5090 ipa_get_ith_polymorhic_call_context (args, j)->stream_out (ob);
5093 ipa_write_indirect_edge_info (ob, e);
5097 /* Stream in edge E from IB. */
5099 static void
5100 ipa_read_edge_info (class lto_input_block *ib,
5101 class data_in *data_in,
5102 struct cgraph_edge *e, bool prevails)
5104 int count = streamer_read_uhwi (ib);
5105 bool contexts_computed = count & 1;
5107 count /= 2;
5108 if (!count)
5109 return;
5110 if (prevails
5111 && (e->possibly_call_in_translation_unit_p ()
5112 /* Also stream in jump functions to builtins in hope that they
5113 will get fnspecs. */
5114 || fndecl_built_in_p (e->callee->decl, BUILT_IN_NORMAL)))
5116 ipa_edge_args *args = ipa_edge_args_sum->get_create (e);
5117 vec_safe_grow_cleared (args->jump_functions, count, true);
5118 if (contexts_computed)
5119 vec_safe_grow_cleared (args->polymorphic_call_contexts, count, true);
5120 for (int k = 0; k < count; k++)
5122 ipa_read_jump_function (ib, ipa_get_ith_jump_func (args, k), e,
5123 data_in, prevails);
5124 if (contexts_computed)
5125 ipa_get_ith_polymorhic_call_context (args, k)->stream_in
5126 (ib, data_in);
5129 else
5131 for (int k = 0; k < count; k++)
5133 struct ipa_jump_func dummy;
5134 ipa_read_jump_function (ib, &dummy, e,
5135 data_in, prevails);
5136 if (contexts_computed)
5138 class ipa_polymorphic_call_context ctx;
5139 ctx.stream_in (ib, data_in);
5145 /* Stream in NODE info from IB. */
5147 static void
5148 ipa_read_node_info (class lto_input_block *ib, struct cgraph_node *node,
5149 class data_in *data_in)
5151 int k;
5152 struct cgraph_edge *e;
5153 struct bitpack_d bp;
5154 bool prevails = node->prevailing_p ();
5155 ipa_node_params *info
5156 = prevails ? ipa_node_params_sum->get_create (node) : NULL;
5158 int param_count = streamer_read_uhwi (ib);
5159 if (prevails)
5161 ipa_alloc_node_params (node, param_count);
5162 for (k = 0; k < param_count; k++)
5163 (*info->descriptors)[k].move_cost = streamer_read_uhwi (ib);
5164 if (ipa_get_param_count (info) != 0)
5165 info->analysis_done = true;
5166 info->node_enqueued = false;
5168 else
5169 for (k = 0; k < param_count; k++)
5170 streamer_read_uhwi (ib);
5172 bp = streamer_read_bitpack (ib);
5173 for (k = 0; k < param_count; k++)
5175 bool load_dereferenced = bp_unpack_value (&bp, 1);
5176 bool used = bp_unpack_value (&bp, 1);
5178 if (prevails)
5180 ipa_set_param_load_dereferenced (info, k, load_dereferenced);
5181 ipa_set_param_used (info, k, used);
5184 for (k = 0; k < param_count; k++)
5186 int nuses = streamer_read_hwi (ib);
5187 tree type = stream_read_tree (ib, data_in);
5189 if (prevails)
5191 ipa_set_controlled_uses (info, k, nuses);
5192 (*info->descriptors)[k].decl_or_type = type;
5195 for (e = node->callees; e; e = e->next_callee)
5196 ipa_read_edge_info (ib, data_in, e, prevails);
5197 for (e = node->indirect_calls; e; e = e->next_callee)
5199 ipa_read_edge_info (ib, data_in, e, prevails);
5200 ipa_read_indirect_edge_info (ib, data_in, e, info);
5204 /* Write jump functions for nodes in SET. */
5206 void
5207 ipa_prop_write_jump_functions (void)
5209 struct output_block *ob;
5210 unsigned int count = 0;
5211 lto_symtab_encoder_iterator lsei;
5212 lto_symtab_encoder_t encoder;
5214 if (!ipa_node_params_sum || !ipa_edge_args_sum)
5215 return;
5217 ob = create_output_block (LTO_section_jump_functions);
5218 encoder = ob->decl_state->symtab_node_encoder;
5219 ob->symbol = NULL;
5220 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
5221 lsei_next_function_in_partition (&lsei))
5223 cgraph_node *node = lsei_cgraph_node (lsei);
5224 if (node->has_gimple_body_p ()
5225 && ipa_node_params_sum->get (node) != NULL)
5226 count++;
5229 streamer_write_uhwi (ob, count);
5231 /* Process all of the functions. */
5232 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
5233 lsei_next_function_in_partition (&lsei))
5235 cgraph_node *node = lsei_cgraph_node (lsei);
5236 if (node->has_gimple_body_p ()
5237 && ipa_node_params_sum->get (node) != NULL)
5238 ipa_write_node_info (ob, node);
5240 streamer_write_char_stream (ob->main_stream, 0);
5241 produce_asm (ob, NULL);
5242 destroy_output_block (ob);
5245 /* Read section in file FILE_DATA of length LEN with data DATA. */
5247 static void
5248 ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
5249 size_t len)
5251 const struct lto_function_header *header =
5252 (const struct lto_function_header *) data;
5253 const int cfg_offset = sizeof (struct lto_function_header);
5254 const int main_offset = cfg_offset + header->cfg_size;
5255 const int string_offset = main_offset + header->main_size;
5256 class data_in *data_in;
5257 unsigned int i;
5258 unsigned int count;
5260 lto_input_block ib_main ((const char *) data + main_offset,
5261 header->main_size, file_data);
5263 data_in =
5264 lto_data_in_create (file_data, (const char *) data + string_offset,
5265 header->string_size, vNULL);
5266 count = streamer_read_uhwi (&ib_main);
5268 for (i = 0; i < count; i++)
5270 unsigned int index;
5271 struct cgraph_node *node;
5272 lto_symtab_encoder_t encoder;
5274 index = streamer_read_uhwi (&ib_main);
5275 encoder = file_data->symtab_node_encoder;
5276 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
5277 index));
5278 gcc_assert (node->definition);
5279 ipa_read_node_info (&ib_main, node, data_in);
5281 lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
5282 len);
5283 lto_data_in_delete (data_in);
5286 /* Read ipcp jump functions. */
5288 void
5289 ipa_prop_read_jump_functions (void)
5291 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
5292 struct lto_file_decl_data *file_data;
5293 unsigned int j = 0;
5295 ipa_check_create_node_params ();
5296 ipa_check_create_edge_args ();
5297 ipa_register_cgraph_hooks ();
5299 while ((file_data = file_data_vec[j++]))
5301 size_t len;
5302 const char *data
5303 = lto_get_summary_section_data (file_data, LTO_section_jump_functions,
5304 &len);
5305 if (data)
5306 ipa_prop_read_section (file_data, data, len);
5310 /* Return true if the IPA-CP transformation summary TS is non-NULL and contains
5311 useful info. */
5312 static bool
5313 useful_ipcp_transformation_info_p (ipcp_transformation *ts)
5315 if (!ts)
5316 return false;
5317 if (!vec_safe_is_empty (ts->m_agg_values)
5318 || !vec_safe_is_empty (ts->m_vr))
5319 return true;
5320 return false;
5323 /* Write into OB IPA-CP transfromation summary TS describing NODE. */
5325 void
5326 write_ipcp_transformation_info (output_block *ob, cgraph_node *node,
5327 ipcp_transformation *ts)
5329 lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
5330 int node_ref = lto_symtab_encoder_encode (encoder, node);
5331 streamer_write_uhwi (ob, node_ref);
5333 streamer_write_uhwi (ob, vec_safe_length (ts->m_agg_values));
5334 for (const ipa_argagg_value &av : ts->m_agg_values)
5336 struct bitpack_d bp;
5338 stream_write_tree (ob, av.value, true);
5339 streamer_write_uhwi (ob, av.unit_offset);
5340 streamer_write_uhwi (ob, av.index);
5342 bp = bitpack_create (ob->main_stream);
5343 bp_pack_value (&bp, av.by_ref, 1);
5344 bp_pack_value (&bp, av.killed, 1);
5345 streamer_write_bitpack (&bp);
5348 streamer_write_uhwi (ob, vec_safe_length (ts->m_vr));
5349 for (const ipa_vr &parm_vr : ts->m_vr)
5350 parm_vr.streamer_write (ob);
5353 /* Stream in the aggregate value replacement chain for NODE from IB. */
5355 static void
5356 read_ipcp_transformation_info (lto_input_block *ib, cgraph_node *node,
5357 data_in *data_in)
5359 unsigned int count, i;
5360 ipcp_transformation_initialize ();
5361 ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
5363 count = streamer_read_uhwi (ib);
5364 if (count > 0)
5366 vec_safe_grow_cleared (ts->m_agg_values, count, true);
5367 for (i = 0; i <count; i++)
5369 ipa_argagg_value *av = &(*ts->m_agg_values)[i];;
5371 av->value = stream_read_tree (ib, data_in);
5372 av->unit_offset = streamer_read_uhwi (ib);
5373 av->index = streamer_read_uhwi (ib);
5375 bitpack_d bp = streamer_read_bitpack (ib);
5376 av->by_ref = bp_unpack_value (&bp, 1);
5377 av->killed = bp_unpack_value (&bp, 1);
5381 count = streamer_read_uhwi (ib);
5382 if (count > 0)
5384 vec_safe_grow_cleared (ts->m_vr, count, true);
5385 for (i = 0; i < count; i++)
5387 ipa_vr *parm_vr;
5388 parm_vr = &(*ts->m_vr)[i];
5389 parm_vr->streamer_read (ib, data_in);
5394 /* Write all aggregate replacement for nodes in set. */
5396 void
5397 ipcp_write_transformation_summaries (void)
5399 struct output_block *ob;
5400 unsigned int count = 0;
5401 lto_symtab_encoder_t encoder;
5403 ob = create_output_block (LTO_section_ipcp_transform);
5404 encoder = ob->decl_state->symtab_node_encoder;
5405 ob->symbol = NULL;
5407 for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
5409 symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
5410 cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
5411 if (!cnode)
5412 continue;
5413 ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
5414 if (useful_ipcp_transformation_info_p (ts)
5415 && lto_symtab_encoder_encode_body_p (encoder, cnode))
5416 count++;
5419 streamer_write_uhwi (ob, count);
5421 for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
5423 symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
5424 cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
5425 if (!cnode)
5426 continue;
5427 ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
5428 if (useful_ipcp_transformation_info_p (ts)
5429 && lto_symtab_encoder_encode_body_p (encoder, cnode))
5430 write_ipcp_transformation_info (ob, cnode, ts);
5432 streamer_write_char_stream (ob->main_stream, 0);
5433 produce_asm (ob, NULL);
5434 destroy_output_block (ob);
5437 /* Read replacements section in file FILE_DATA of length LEN with data
5438 DATA. */
5440 static void
5441 read_replacements_section (struct lto_file_decl_data *file_data,
5442 const char *data,
5443 size_t len)
5445 const struct lto_function_header *header =
5446 (const struct lto_function_header *) data;
5447 const int cfg_offset = sizeof (struct lto_function_header);
5448 const int main_offset = cfg_offset + header->cfg_size;
5449 const int string_offset = main_offset + header->main_size;
5450 class data_in *data_in;
5451 unsigned int i;
5452 unsigned int count;
5454 lto_input_block ib_main ((const char *) data + main_offset,
5455 header->main_size, file_data);
5457 data_in = lto_data_in_create (file_data, (const char *) data + string_offset,
5458 header->string_size, vNULL);
5459 count = streamer_read_uhwi (&ib_main);
5461 for (i = 0; i < count; i++)
5463 unsigned int index;
5464 struct cgraph_node *node;
5465 lto_symtab_encoder_t encoder;
5467 index = streamer_read_uhwi (&ib_main);
5468 encoder = file_data->symtab_node_encoder;
5469 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
5470 index));
5471 read_ipcp_transformation_info (&ib_main, node, data_in);
5473 lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
5474 len);
5475 lto_data_in_delete (data_in);
5478 /* Read IPA-CP aggregate replacements. */
5480 void
5481 ipcp_read_transformation_summaries (void)
5483 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
5484 struct lto_file_decl_data *file_data;
5485 unsigned int j = 0;
5487 while ((file_data = file_data_vec[j++]))
5489 size_t len;
5490 const char *data
5491 = lto_get_summary_section_data (file_data, LTO_section_ipcp_transform,
5492 &len);
5493 if (data)
5494 read_replacements_section (file_data, data, len);
5498 /* Adjust the aggregate replacements in TS to reflect any parameter removals
5499 which might have already taken place. If after adjustments there are no
5500 aggregate replacements left, the m_agg_values will be set to NULL. In other
5501 cases, it may be shrunk. */
5503 static void
5504 adjust_agg_replacement_values (cgraph_node *node, ipcp_transformation *ts)
5506 clone_info *cinfo = clone_info::get (node);
5507 if (!cinfo || !cinfo->param_adjustments)
5508 return;
5510 auto_vec<int, 16> new_indices;
5511 cinfo->param_adjustments->get_updated_indices (&new_indices);
5512 bool removed_item = false;
5513 unsigned dst_index = 0;
5514 unsigned count = ts->m_agg_values->length ();
5515 for (unsigned i = 0; i < count; i++)
5517 ipa_argagg_value *v = &(*ts->m_agg_values)[i];
5518 gcc_checking_assert (v->index >= 0);
5520 int new_idx = -1;
5521 if ((unsigned) v->index < new_indices.length ())
5522 new_idx = new_indices[v->index];
5524 if (new_idx >= 0)
5526 v->index = new_idx;
5527 if (removed_item)
5528 (*ts->m_agg_values)[dst_index] = *v;
5529 dst_index++;
5531 else
5532 removed_item = true;
5535 if (dst_index == 0)
5537 ggc_free (ts->m_agg_values);
5538 ts->m_agg_values = NULL;
5540 else if (removed_item)
5541 ts->m_agg_values->truncate (dst_index);
5543 return;
5546 /* Dominator walker driving the ipcp modification phase. */
5548 class ipcp_modif_dom_walker : public dom_walker
5550 public:
5551 ipcp_modif_dom_walker (struct ipa_func_body_info *fbi,
5552 vec<ipa_param_descriptor, va_gc> *descs,
5553 ipcp_transformation *ts, bool *sc)
5554 : dom_walker (CDI_DOMINATORS), m_fbi (fbi), m_descriptors (descs),
5555 m_ts (ts), m_something_changed (sc) {}
5557 edge before_dom_children (basic_block) final override;
5558 bool cleanup_eh ()
5559 { return gimple_purge_all_dead_eh_edges (m_need_eh_cleanup); }
5561 private:
5562 struct ipa_func_body_info *m_fbi;
5563 vec<ipa_param_descriptor, va_gc> *m_descriptors;
5564 ipcp_transformation *m_ts;
5565 bool *m_something_changed;
5566 auto_bitmap m_need_eh_cleanup;
5569 edge
5570 ipcp_modif_dom_walker::before_dom_children (basic_block bb)
5572 gimple_stmt_iterator gsi;
5573 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
5575 gimple *stmt = gsi_stmt (gsi);
5576 tree rhs, val, t;
5577 HOST_WIDE_INT bit_offset;
5578 poly_int64 size;
5579 int index;
5580 bool by_ref, vce;
5582 if (!gimple_assign_load_p (stmt))
5583 continue;
5584 rhs = gimple_assign_rhs1 (stmt);
5585 if (!is_gimple_reg_type (TREE_TYPE (rhs)))
5586 continue;
5588 vce = false;
5589 t = rhs;
5590 while (handled_component_p (t))
5592 /* V_C_E can do things like convert an array of integers to one
5593 bigger integer and similar things we do not handle below. */
5594 if (TREE_CODE (t) == VIEW_CONVERT_EXPR)
5596 vce = true;
5597 break;
5599 t = TREE_OPERAND (t, 0);
5601 if (vce)
5602 continue;
5604 if (!ipa_load_from_parm_agg (m_fbi, m_descriptors, stmt, rhs, &index,
5605 &bit_offset, &size, &by_ref))
5606 continue;
5607 unsigned unit_offset = bit_offset / BITS_PER_UNIT;
5608 ipa_argagg_value_list avl (m_ts);
5609 tree v = avl.get_value (index, unit_offset, by_ref);
5611 if (!v
5612 || maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (v))), size))
5613 continue;
5615 gcc_checking_assert (is_gimple_ip_invariant (v));
5616 if (!useless_type_conversion_p (TREE_TYPE (rhs), TREE_TYPE (v)))
5618 if (fold_convertible_p (TREE_TYPE (rhs), v))
5619 val = fold_build1 (NOP_EXPR, TREE_TYPE (rhs), v);
5620 else if (TYPE_SIZE (TREE_TYPE (rhs))
5621 == TYPE_SIZE (TREE_TYPE (v)))
5622 val = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (rhs), v);
5623 else
5625 if (dump_file)
5627 fprintf (dump_file, " const ");
5628 print_generic_expr (dump_file, v);
5629 fprintf (dump_file, " can't be converted to type of ");
5630 print_generic_expr (dump_file, rhs);
5631 fprintf (dump_file, "\n");
5633 continue;
5636 else
5637 val = v;
5639 if (dump_file && (dump_flags & TDF_DETAILS))
5641 fprintf (dump_file, "Modifying stmt:\n ");
5642 print_gimple_stmt (dump_file, stmt, 0);
5644 gimple_assign_set_rhs_from_tree (&gsi, val);
5645 update_stmt (stmt);
5647 if (dump_file && (dump_flags & TDF_DETAILS))
5649 fprintf (dump_file, "into:\n ");
5650 print_gimple_stmt (dump_file, stmt, 0);
5651 fprintf (dump_file, "\n");
5654 *m_something_changed = true;
5655 if (maybe_clean_eh_stmt (stmt))
5656 bitmap_set_bit (m_need_eh_cleanup, bb->index);
5658 return NULL;
5661 /* If IPA-CP discovered a constant in parameter PARM at OFFSET of a given SIZE
5662 - whether passed by reference or not is given by BY_REF - return that
5663 constant. Otherwise return NULL_TREE. The is supposed to be used only
5664 after clone materialization and transformation is done (because it asserts
5665 that killed constants have been pruned). */
5667 tree
5668 ipcp_get_aggregate_const (struct function *func, tree parm, bool by_ref,
5669 HOST_WIDE_INT bit_offset, HOST_WIDE_INT bit_size)
5671 cgraph_node *node = cgraph_node::get (func->decl);
5672 ipcp_transformation *ts = ipcp_get_transformation_summary (node);
5674 if (!ts || !ts->m_agg_values)
5675 return NULL_TREE;
5677 int index = ts->get_param_index (func->decl, parm);
5678 if (index < 0)
5679 return NULL_TREE;
5681 ipa_argagg_value_list avl (ts);
5682 unsigned unit_offset = bit_offset / BITS_PER_UNIT;
5683 const ipa_argagg_value *av = avl.get_elt (index, unit_offset);
5684 if (!av || av->by_ref != by_ref)
5685 return NULL_TREE;
5686 gcc_assert (!av->killed);
5687 tree v = av->value;
5688 if (!v
5689 || maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (v))), bit_size))
5690 return NULL_TREE;
5692 return v;
5695 /* Return true if we have recorded VALUE and MASK about PARM.
5696 Set VALUE and MASk accordingly. */
5698 bool
5699 ipcp_get_parm_bits (tree parm, tree *value, widest_int *mask)
5701 cgraph_node *cnode = cgraph_node::get (current_function_decl);
5702 ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
5703 if (!ts
5704 || vec_safe_length (ts->m_vr) == 0
5705 || !irange::supports_p (TREE_TYPE (parm)))
5706 return false;
5708 int i = ts->get_param_index (current_function_decl, parm);
5709 if (i < 0)
5710 return false;
5711 clone_info *cinfo = clone_info::get (cnode);
5712 if (cinfo && cinfo->param_adjustments)
5714 i = cinfo->param_adjustments->get_original_index (i);
5715 if (i < 0)
5716 return false;
5719 vec<ipa_vr, va_gc> &vr = *ts->m_vr;
5720 if (!vr[i].known_p ())
5721 return false;
5722 Value_Range tmp;
5723 vr[i].get_vrange (tmp);
5724 if (tmp.undefined_p () || tmp.varying_p ())
5725 return false;
5726 irange &r = as_a <irange> (tmp);
5727 irange_bitmask bm = r.get_bitmask ();
5728 *mask = widest_int::from (bm.mask (), TYPE_SIGN (TREE_TYPE (parm)));
5729 *value = wide_int_to_tree (TREE_TYPE (parm), bm.value ());
5730 return true;
5733 /* Update value range of formal parameters of NODE as described in TS. */
5735 static void
5736 ipcp_update_vr (struct cgraph_node *node, ipcp_transformation *ts)
5738 if (vec_safe_is_empty (ts->m_vr))
5739 return;
5740 const vec<ipa_vr, va_gc> &vr = *ts->m_vr;
5741 unsigned count = vr.length ();
5742 if (!count)
5743 return;
5745 auto_vec<int, 16> new_indices;
5746 bool need_remapping = false;
5747 clone_info *cinfo = clone_info::get (node);
5748 if (cinfo && cinfo->param_adjustments)
5750 cinfo->param_adjustments->get_updated_indices (&new_indices);
5751 need_remapping = true;
5753 auto_vec <tree, 16> parm_decls;
5754 push_function_arg_decls (&parm_decls, node->decl);
5756 for (unsigned i = 0; i < count; ++i)
5758 tree parm;
5759 int remapped_idx;
5760 if (need_remapping)
5762 if (i >= new_indices.length ())
5763 continue;
5764 remapped_idx = new_indices[i];
5765 if (remapped_idx < 0)
5766 continue;
5768 else
5769 remapped_idx = i;
5771 parm = parm_decls[remapped_idx];
5773 gcc_checking_assert (parm);
5774 tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl), parm);
5776 if (!ddef || !is_gimple_reg (parm))
5777 continue;
5779 if (vr[i].known_p ())
5781 Value_Range tmp;
5782 vr[i].get_vrange (tmp);
5784 if (!tmp.undefined_p () && !tmp.varying_p ())
5786 if (dump_file)
5788 fprintf (dump_file, "Setting value range of param %u "
5789 "(now %i) ", i, remapped_idx);
5790 tmp.dump (dump_file);
5791 fprintf (dump_file, "]\n");
5793 set_range_info (ddef, tmp);
5795 if (POINTER_TYPE_P (TREE_TYPE (parm))
5796 && opt_for_fn (node->decl, flag_ipa_bit_cp))
5798 irange &r = as_a<irange> (tmp);
5799 irange_bitmask bm = r.get_bitmask ();
5800 unsigned tem = bm.mask ().to_uhwi ();
5801 unsigned HOST_WIDE_INT bitpos = bm.value ().to_uhwi ();
5802 unsigned align = tem & -tem;
5803 unsigned misalign = bitpos & (align - 1);
5805 if (align > 1)
5807 if (dump_file)
5809 fprintf (dump_file,
5810 "Adjusting mask for param %u to ", i);
5811 print_hex (bm.mask (), dump_file);
5812 fprintf (dump_file, "\n");
5815 if (dump_file)
5816 fprintf (dump_file,
5817 "Adjusting align: %u, misalign: %u\n",
5818 align, misalign);
5820 unsigned old_align, old_misalign;
5821 struct ptr_info_def *pi = get_ptr_info (ddef);
5822 bool old_known = get_ptr_info_alignment (pi, &old_align,
5823 &old_misalign);
5825 if (old_known && old_align > align)
5827 if (dump_file)
5829 fprintf (dump_file,
5830 "But alignment was already %u.\n",
5831 old_align);
5832 if ((old_misalign & (align - 1)) != misalign)
5833 fprintf (dump_file,
5834 "old_misalign (%u) and misalign "
5835 "(%u) mismatch\n",
5836 old_misalign, misalign);
5838 continue;
5841 if (dump_file
5842 && old_known
5843 && ((misalign & (old_align - 1)) != old_misalign))
5844 fprintf (dump_file,
5845 "old_misalign (%u) and misalign (%u) "
5846 "mismatch\n",
5847 old_misalign, misalign);
5849 set_ptr_info_alignment (pi, align, misalign);
5852 else if (dump_file && INTEGRAL_TYPE_P (TREE_TYPE (parm)))
5854 irange &r = as_a<irange> (tmp);
5855 irange_bitmask bm = r.get_bitmask ();
5856 unsigned prec = TYPE_PRECISION (TREE_TYPE (parm));
5857 if (wi::ne_p (bm.mask (), wi::shwi (-1, prec)))
5859 fprintf (dump_file,
5860 "Adjusting mask for param %u to ", i);
5861 print_hex (bm.mask (), dump_file);
5862 fprintf (dump_file, "\n");
5870 /* IPCP transformation phase doing propagation of aggregate values. */
5872 unsigned int
5873 ipcp_transform_function (struct cgraph_node *node)
5875 struct ipa_func_body_info fbi;
5876 int param_count;
5878 gcc_checking_assert (cfun);
5879 gcc_checking_assert (current_function_decl);
5881 if (dump_file)
5882 fprintf (dump_file, "Modification phase of node %s\n",
5883 node->dump_name ());
5885 ipcp_transformation *ts = ipcp_get_transformation_summary (node);
5886 if (!ts
5887 || (vec_safe_is_empty (ts->m_agg_values)
5888 && vec_safe_is_empty (ts->m_vr)))
5889 return 0;
5891 ts->maybe_create_parm_idx_map (cfun->decl);
5892 ipcp_update_vr (node, ts);
5893 if (vec_safe_is_empty (ts->m_agg_values))
5894 return 0;
5895 param_count = count_formal_params (node->decl);
5896 if (param_count == 0)
5897 return 0;
5899 adjust_agg_replacement_values (node, ts);
5900 if (vec_safe_is_empty (ts->m_agg_values))
5902 if (dump_file)
5903 fprintf (dump_file, " All affected aggregate parameters were either "
5904 "removed or converted into scalars, phase done.\n");
5905 return 0;
5907 if (dump_file)
5909 fprintf (dump_file, " Aggregate replacements:");
5910 ipa_argagg_value_list avs (ts);
5911 avs.dump (dump_file);
5914 fbi.node = node;
5915 fbi.info = NULL;
5916 fbi.bb_infos = vNULL;
5917 fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
5918 fbi.param_count = param_count;
5919 fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps);
5921 vec<ipa_param_descriptor, va_gc> *descriptors = NULL;
5922 vec_safe_grow_cleared (descriptors, param_count, true);
5923 ipa_populate_param_decls (node, *descriptors);
5924 bool modified_mem_access = false;
5925 calculate_dominance_info (CDI_DOMINATORS);
5926 ipcp_modif_dom_walker walker (&fbi, descriptors, ts, &modified_mem_access);
5927 walker.walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
5928 free_dominance_info (CDI_DOMINATORS);
5929 bool cfg_changed = walker.cleanup_eh ();
5931 int i;
5932 struct ipa_bb_info *bi;
5933 FOR_EACH_VEC_ELT (fbi.bb_infos, i, bi)
5934 free_ipa_bb_info (bi);
5935 fbi.bb_infos.release ();
5937 ts->remove_argaggs_if ([](const ipa_argagg_value &v)
5939 return v.killed;
5942 vec_free (descriptors);
5943 if (cfg_changed)
5944 delete_unreachable_blocks_update_callgraph (node, false);
5946 return modified_mem_access ? TODO_update_ssa_only_virtuals : 0;
5949 /* Record that current function return value range is VAL. */
5951 void
5952 ipa_record_return_value_range (Value_Range val)
5954 cgraph_node *n = cgraph_node::get (current_function_decl);
5955 if (!ipa_return_value_sum)
5957 if (!ipa_vr_hash_table)
5958 ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
5959 ipa_return_value_sum = new (ggc_alloc_no_dtor <ipa_return_value_sum_t> ())
5960 ipa_return_value_sum_t (symtab, true);
5961 ipa_return_value_sum->disable_insertion_hook ();
5963 ipa_return_value_sum->get_create (n)->vr = ipa_get_value_range (val);
5964 if (dump_file && (dump_flags & TDF_DETAILS))
5966 fprintf (dump_file, "Recording return range ");
5967 val.dump (dump_file);
5968 fprintf (dump_file, "\n");
5972 /* Return true if value range of DECL is known and if so initialize RANGE. */
5974 bool
5975 ipa_return_value_range (Value_Range &range, tree decl)
5977 cgraph_node *n = cgraph_node::get (decl);
5978 if (!n || !ipa_return_value_sum)
5979 return false;
5980 enum availability avail;
5981 n = n->ultimate_alias_target (&avail);
5982 if (avail < AVAIL_AVAILABLE)
5983 return false;
5984 if (n->decl != decl && !useless_type_conversion_p (TREE_TYPE (decl), TREE_TYPE (n->decl)))
5985 return false;
5986 ipa_return_value_summary *v = ipa_return_value_sum->get (n);
5987 if (!v)
5988 return false;
5989 v->vr->get_vrange (range);
5990 return true;
5993 /* Reset all state within ipa-prop.cc so that we can rerun the compiler
5994 within the same process. For use by toplev::finalize. */
5996 void
5997 ipa_prop_cc_finalize (void)
5999 if (function_insertion_hook_holder)
6000 symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
6001 function_insertion_hook_holder = NULL;
6003 if (ipa_edge_args_sum)
6004 ggc_delete (ipa_edge_args_sum);
6005 ipa_edge_args_sum = NULL;
6007 if (ipa_node_params_sum)
6008 ggc_delete (ipa_node_params_sum);
6009 ipa_node_params_sum = NULL;
6012 #include "gt-ipa-prop.h"