Revise -mdisable-fpregs option and add new -msoft-mult option
[official-gcc.git] / gcc / ipa-prop.c
blob443f21ce61b38e9667066f77ba541ade767ffc6b
1 /* Interprocedural analyses.
2 Copyright (C) 2005-2021 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-fold.h"
35 #include "tree-eh.h"
36 #include "calls.h"
37 #include "stor-layout.h"
38 #include "print-tree.h"
39 #include "gimplify.h"
40 #include "gimple-iterator.h"
41 #include "gimplify-me.h"
42 #include "gimple-walk.h"
43 #include "symbol-summary.h"
44 #include "ipa-prop.h"
45 #include "tree-cfg.h"
46 #include "tree-dfa.h"
47 #include "tree-inline.h"
48 #include "ipa-fnsummary.h"
49 #include "gimple-pretty-print.h"
50 #include "ipa-utils.h"
51 #include "dbgcnt.h"
52 #include "domwalk.h"
53 #include "builtins.h"
54 #include "tree-cfgcleanup.h"
55 #include "options.h"
56 #include "symtab-clones.h"
57 #include "attr-fnspec.h"
58 #include "gimple-range.h"
60 /* Function summary where the parameter infos are actually stored. */
61 ipa_node_params_t *ipa_node_params_sum = NULL;
63 function_summary <ipcp_transformation *> *ipcp_transformation_sum = NULL;
65 /* Edge summary for IPA-CP edge information. */
66 ipa_edge_args_sum_t *ipa_edge_args_sum;
68 /* Traits for a hash table for reusing already existing ipa_bits. */
70 struct ipa_bit_ggc_hash_traits : public ggc_cache_remove <ipa_bits *>
72 typedef ipa_bits *value_type;
73 typedef ipa_bits *compare_type;
74 static hashval_t
75 hash (const ipa_bits *p)
77 hashval_t t = (hashval_t) p->value.to_shwi ();
78 return iterative_hash_host_wide_int (p->mask.to_shwi (), t);
80 static bool
81 equal (const ipa_bits *a, const ipa_bits *b)
83 return a->value == b->value && a->mask == b->mask;
85 static const bool empty_zero_p = true;
86 static void
87 mark_empty (ipa_bits *&p)
89 p = NULL;
91 static bool
92 is_empty (const ipa_bits *p)
94 return p == NULL;
96 static bool
97 is_deleted (const ipa_bits *p)
99 return p == reinterpret_cast<const ipa_bits *> (1);
101 static void
102 mark_deleted (ipa_bits *&p)
104 p = reinterpret_cast<ipa_bits *> (1);
108 /* Hash table for avoid repeated allocations of equal ipa_bits. */
109 static GTY ((cache)) hash_table<ipa_bit_ggc_hash_traits> *ipa_bits_hash_table;
111 /* Traits for a hash table for reusing value_ranges used for IPA. Note that
112 the equiv bitmap is not hashed and is expected to be NULL. */
114 struct ipa_vr_ggc_hash_traits : public ggc_cache_remove <value_range *>
116 typedef value_range *value_type;
117 typedef value_range *compare_type;
118 static hashval_t
119 hash (const value_range *p)
121 inchash::hash hstate (p->kind ());
122 inchash::add_expr (p->min (), hstate);
123 inchash::add_expr (p->max (), hstate);
124 return hstate.end ();
126 static bool
127 equal (const value_range *a, const value_range *b)
129 return (a->equal_p (*b)
130 && types_compatible_p (a->type (), b->type ()));
132 static const bool empty_zero_p = true;
133 static void
134 mark_empty (value_range *&p)
136 p = NULL;
138 static bool
139 is_empty (const value_range *p)
141 return p == NULL;
143 static bool
144 is_deleted (const value_range *p)
146 return p == reinterpret_cast<const value_range *> (1);
148 static void
149 mark_deleted (value_range *&p)
151 p = reinterpret_cast<value_range *> (1);
155 /* Hash table for avoid repeated allocations of equal value_ranges. */
156 static GTY ((cache)) hash_table<ipa_vr_ggc_hash_traits> *ipa_vr_hash_table;
158 /* Holders of ipa cgraph hooks: */
159 static struct cgraph_node_hook_list *function_insertion_hook_holder;
161 /* Description of a reference to an IPA constant. */
162 struct ipa_cst_ref_desc
164 /* Edge that corresponds to the statement which took the reference. */
165 struct cgraph_edge *cs;
166 /* Linked list of duplicates created when call graph edges are cloned. */
167 struct ipa_cst_ref_desc *next_duplicate;
168 /* Number of references in IPA structures, IPA_UNDESCRIBED_USE if the value
169 if out of control. */
170 int refcount;
173 /* Allocation pool for reference descriptions. */
175 static object_allocator<ipa_cst_ref_desc> ipa_refdesc_pool
176 ("IPA-PROP ref descriptions");
178 /* Return true if DECL_FUNCTION_SPECIFIC_OPTIMIZATION of the decl associated
179 with NODE should prevent us from analyzing it for the purposes of IPA-CP. */
181 static bool
182 ipa_func_spec_opts_forbid_analysis_p (struct cgraph_node *node)
184 tree fs_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (node->decl);
186 if (!fs_opts)
187 return false;
188 return !opt_for_fn (node->decl, optimize) || !opt_for_fn (node->decl, flag_ipa_cp);
191 /* Return index of the formal whose tree is PTREE in function which corresponds
192 to INFO. */
194 static int
195 ipa_get_param_decl_index_1 (vec<ipa_param_descriptor, va_gc> *descriptors,
196 tree ptree)
198 int i, count;
200 count = vec_safe_length (descriptors);
201 for (i = 0; i < count; i++)
202 if ((*descriptors)[i].decl_or_type == ptree)
203 return i;
205 return -1;
208 /* Return index of the formal whose tree is PTREE in function which corresponds
209 to INFO. */
212 ipa_get_param_decl_index (class ipa_node_params *info, tree ptree)
214 return ipa_get_param_decl_index_1 (info->descriptors, ptree);
217 /* Populate the param_decl field in parameter DESCRIPTORS that correspond to
218 NODE. */
220 static void
221 ipa_populate_param_decls (struct cgraph_node *node,
222 vec<ipa_param_descriptor, va_gc> &descriptors)
224 tree fndecl;
225 tree fnargs;
226 tree parm;
227 int param_num;
229 fndecl = node->decl;
230 gcc_assert (gimple_has_body_p (fndecl));
231 fnargs = DECL_ARGUMENTS (fndecl);
232 param_num = 0;
233 for (parm = fnargs; parm; parm = DECL_CHAIN (parm))
235 descriptors[param_num].decl_or_type = parm;
236 unsigned int cost = estimate_move_cost (TREE_TYPE (parm), true);
237 descriptors[param_num].move_cost = cost;
238 /* Watch overflow, move_cost is a bitfield. */
239 gcc_checking_assert (cost == descriptors[param_num].move_cost);
240 param_num++;
244 /* Return how many formal parameters FNDECL has. */
247 count_formal_params (tree fndecl)
249 tree parm;
250 int count = 0;
251 gcc_assert (gimple_has_body_p (fndecl));
253 for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
254 count++;
256 return count;
259 /* Return the declaration of Ith formal parameter of the function corresponding
260 to INFO. Note there is no setter function as this array is built just once
261 using ipa_initialize_node_params. */
263 void
264 ipa_dump_param (FILE *file, class ipa_node_params *info, int i)
266 fprintf (file, "param #%i", i);
267 if ((*info->descriptors)[i].decl_or_type)
269 fprintf (file, " ");
270 print_generic_expr (file, (*info->descriptors)[i].decl_or_type);
274 /* If necessary, allocate vector of parameter descriptors in info of NODE.
275 Return true if they were allocated, false if not. */
277 static bool
278 ipa_alloc_node_params (struct cgraph_node *node, int param_count)
280 ipa_node_params *info = ipa_node_params_sum->get_create (node);
282 if (!info->descriptors && param_count)
284 vec_safe_grow_cleared (info->descriptors, param_count, true);
285 return true;
287 else
288 return false;
291 /* Initialize the ipa_node_params structure associated with NODE by counting
292 the function parameters, creating the descriptors and populating their
293 param_decls. */
295 void
296 ipa_initialize_node_params (struct cgraph_node *node)
298 ipa_node_params *info = ipa_node_params_sum->get_create (node);
300 if (!info->descriptors
301 && ipa_alloc_node_params (node, count_formal_params (node->decl)))
302 ipa_populate_param_decls (node, *info->descriptors);
305 /* Print the jump functions associated with call graph edge CS to file F. */
307 static void
308 ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
310 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
311 int count = ipa_get_cs_argument_count (args);
313 for (int i = 0; i < count; i++)
315 struct ipa_jump_func *jump_func;
316 enum jump_func_type type;
318 jump_func = ipa_get_ith_jump_func (args, i);
319 type = jump_func->type;
321 fprintf (f, " param %d: ", i);
322 if (type == IPA_JF_UNKNOWN)
323 fprintf (f, "UNKNOWN\n");
324 else if (type == IPA_JF_CONST)
326 tree val = jump_func->value.constant.value;
327 fprintf (f, "CONST: ");
328 print_generic_expr (f, val);
329 if (TREE_CODE (val) == ADDR_EXPR
330 && TREE_CODE (TREE_OPERAND (val, 0)) == CONST_DECL)
332 fprintf (f, " -> ");
333 print_generic_expr (f, DECL_INITIAL (TREE_OPERAND (val, 0)));
335 fprintf (f, "\n");
337 else if (type == IPA_JF_PASS_THROUGH)
339 fprintf (f, "PASS THROUGH: ");
340 fprintf (f, "%d, op %s",
341 jump_func->value.pass_through.formal_id,
342 get_tree_code_name(jump_func->value.pass_through.operation));
343 if (jump_func->value.pass_through.operation != NOP_EXPR)
345 fprintf (f, " ");
346 print_generic_expr (f, jump_func->value.pass_through.operand);
348 if (jump_func->value.pass_through.agg_preserved)
349 fprintf (f, ", agg_preserved");
350 fprintf (f, "\n");
352 else if (type == IPA_JF_ANCESTOR)
354 fprintf (f, "ANCESTOR: ");
355 fprintf (f, "%d, offset " HOST_WIDE_INT_PRINT_DEC,
356 jump_func->value.ancestor.formal_id,
357 jump_func->value.ancestor.offset);
358 if (jump_func->value.ancestor.agg_preserved)
359 fprintf (f, ", agg_preserved");
360 fprintf (f, "\n");
363 if (jump_func->agg.items)
365 struct ipa_agg_jf_item *item;
366 int j;
368 fprintf (f, " Aggregate passed by %s:\n",
369 jump_func->agg.by_ref ? "reference" : "value");
370 FOR_EACH_VEC_ELT (*jump_func->agg.items, j, item)
372 fprintf (f, " offset: " HOST_WIDE_INT_PRINT_DEC ", ",
373 item->offset);
374 fprintf (f, "type: ");
375 print_generic_expr (f, item->type);
376 fprintf (f, ", ");
377 if (item->jftype == IPA_JF_PASS_THROUGH)
378 fprintf (f, "PASS THROUGH: %d,",
379 item->value.pass_through.formal_id);
380 else if (item->jftype == IPA_JF_LOAD_AGG)
382 fprintf (f, "LOAD AGG: %d",
383 item->value.pass_through.formal_id);
384 fprintf (f, " [offset: " HOST_WIDE_INT_PRINT_DEC ", by %s],",
385 item->value.load_agg.offset,
386 item->value.load_agg.by_ref ? "reference"
387 : "value");
390 if (item->jftype == IPA_JF_PASS_THROUGH
391 || item->jftype == IPA_JF_LOAD_AGG)
393 fprintf (f, " op %s",
394 get_tree_code_name (item->value.pass_through.operation));
395 if (item->value.pass_through.operation != NOP_EXPR)
397 fprintf (f, " ");
398 print_generic_expr (f, item->value.pass_through.operand);
401 else if (item->jftype == IPA_JF_CONST)
403 fprintf (f, "CONST: ");
404 print_generic_expr (f, item->value.constant);
406 else if (item->jftype == IPA_JF_UNKNOWN)
407 fprintf (f, "UNKNOWN: " HOST_WIDE_INT_PRINT_DEC " bits",
408 tree_to_uhwi (TYPE_SIZE (item->type)));
409 fprintf (f, "\n");
413 class ipa_polymorphic_call_context *ctx
414 = ipa_get_ith_polymorhic_call_context (args, i);
415 if (ctx && !ctx->useless_p ())
417 fprintf (f, " Context: ");
418 ctx->dump (dump_file);
421 if (jump_func->bits)
423 fprintf (f, " value: ");
424 print_hex (jump_func->bits->value, f);
425 fprintf (f, ", mask: ");
426 print_hex (jump_func->bits->mask, f);
427 fprintf (f, "\n");
429 else
430 fprintf (f, " Unknown bits\n");
432 if (jump_func->m_vr)
434 fprintf (f, " VR ");
435 fprintf (f, "%s[",
436 (jump_func->m_vr->kind () == VR_ANTI_RANGE) ? "~" : "");
437 print_decs (wi::to_wide (jump_func->m_vr->min ()), f);
438 fprintf (f, ", ");
439 print_decs (wi::to_wide (jump_func->m_vr->max ()), f);
440 fprintf (f, "]\n");
442 else
443 fprintf (f, " Unknown VR\n");
448 /* Print the jump functions of all arguments on all call graph edges going from
449 NODE to file F. */
451 void
452 ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
454 struct cgraph_edge *cs;
456 fprintf (f, " Jump functions of caller %s:\n", node->dump_name ());
457 for (cs = node->callees; cs; cs = cs->next_callee)
460 fprintf (f, " callsite %s -> %s : \n",
461 node->dump_name (),
462 cs->callee->dump_name ());
463 if (!ipa_edge_args_info_available_for_edge_p (cs))
464 fprintf (f, " no arg info\n");
465 else
466 ipa_print_node_jump_functions_for_edge (f, cs);
469 for (cs = node->indirect_calls; cs; cs = cs->next_callee)
471 class cgraph_indirect_call_info *ii;
473 ii = cs->indirect_info;
474 if (ii->agg_contents)
475 fprintf (f, " indirect %s callsite, calling param %i, "
476 "offset " HOST_WIDE_INT_PRINT_DEC ", %s",
477 ii->member_ptr ? "member ptr" : "aggregate",
478 ii->param_index, ii->offset,
479 ii->by_ref ? "by reference" : "by_value");
480 else
481 fprintf (f, " indirect %s callsite, calling param %i, "
482 "offset " HOST_WIDE_INT_PRINT_DEC,
483 ii->polymorphic ? "polymorphic" : "simple", ii->param_index,
484 ii->offset);
486 if (cs->call_stmt)
488 fprintf (f, ", for stmt ");
489 print_gimple_stmt (f, cs->call_stmt, 0, TDF_SLIM);
491 else
492 fprintf (f, "\n");
493 if (ii->polymorphic)
494 ii->context.dump (f);
495 if (!ipa_edge_args_info_available_for_edge_p (cs))
496 fprintf (f, " no arg info\n");
497 else
498 ipa_print_node_jump_functions_for_edge (f, cs);
502 /* Print ipa_jump_func data structures of all nodes in the call graph to F. */
504 void
505 ipa_print_all_jump_functions (FILE *f)
507 struct cgraph_node *node;
509 fprintf (f, "\nJump functions:\n");
510 FOR_EACH_FUNCTION (node)
512 ipa_print_node_jump_functions (f, node);
516 /* Set jfunc to be a know-really nothing jump function. */
518 static void
519 ipa_set_jf_unknown (struct ipa_jump_func *jfunc)
521 jfunc->type = IPA_JF_UNKNOWN;
524 /* Set JFUNC to be a copy of another jmp (to be used by jump function
525 combination code). The two functions will share their rdesc. */
527 static void
528 ipa_set_jf_cst_copy (struct ipa_jump_func *dst,
529 struct ipa_jump_func *src)
532 gcc_checking_assert (src->type == IPA_JF_CONST);
533 dst->type = IPA_JF_CONST;
534 dst->value.constant = src->value.constant;
537 /* Set JFUNC to be a constant jmp function. */
539 static void
540 ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
541 struct cgraph_edge *cs)
543 jfunc->type = IPA_JF_CONST;
544 jfunc->value.constant.value = unshare_expr_without_location (constant);
546 if (TREE_CODE (constant) == ADDR_EXPR
547 && (TREE_CODE (TREE_OPERAND (constant, 0)) == FUNCTION_DECL
548 || (TREE_CODE (TREE_OPERAND (constant, 0)) == VAR_DECL
549 && TREE_STATIC (TREE_OPERAND (constant, 0)))))
551 struct ipa_cst_ref_desc *rdesc;
553 rdesc = ipa_refdesc_pool.allocate ();
554 rdesc->cs = cs;
555 rdesc->next_duplicate = NULL;
556 rdesc->refcount = 1;
557 jfunc->value.constant.rdesc = rdesc;
559 else
560 jfunc->value.constant.rdesc = NULL;
563 /* Set JFUNC to be a simple pass-through jump function. */
564 static void
565 ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
566 bool agg_preserved)
568 jfunc->type = IPA_JF_PASS_THROUGH;
569 jfunc->value.pass_through.operand = NULL_TREE;
570 jfunc->value.pass_through.formal_id = formal_id;
571 jfunc->value.pass_through.operation = NOP_EXPR;
572 jfunc->value.pass_through.agg_preserved = agg_preserved;
575 /* Set JFUNC to be an unary pass through jump function. */
577 static void
578 ipa_set_jf_unary_pass_through (struct ipa_jump_func *jfunc, int formal_id,
579 enum tree_code operation)
581 jfunc->type = IPA_JF_PASS_THROUGH;
582 jfunc->value.pass_through.operand = NULL_TREE;
583 jfunc->value.pass_through.formal_id = formal_id;
584 jfunc->value.pass_through.operation = operation;
585 jfunc->value.pass_through.agg_preserved = false;
587 /* Set JFUNC to be an arithmetic pass through jump function. */
589 static void
590 ipa_set_jf_arith_pass_through (struct ipa_jump_func *jfunc, int formal_id,
591 tree operand, enum tree_code operation)
593 jfunc->type = IPA_JF_PASS_THROUGH;
594 jfunc->value.pass_through.operand = unshare_expr_without_location (operand);
595 jfunc->value.pass_through.formal_id = formal_id;
596 jfunc->value.pass_through.operation = operation;
597 jfunc->value.pass_through.agg_preserved = false;
600 /* Set JFUNC to be an ancestor jump function. */
602 static void
603 ipa_set_ancestor_jf (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
604 int formal_id, bool agg_preserved)
606 jfunc->type = IPA_JF_ANCESTOR;
607 jfunc->value.ancestor.formal_id = formal_id;
608 jfunc->value.ancestor.offset = offset;
609 jfunc->value.ancestor.agg_preserved = agg_preserved;
612 /* Get IPA BB information about the given BB. FBI is the context of analyzis
613 of this function body. */
615 static struct ipa_bb_info *
616 ipa_get_bb_info (struct ipa_func_body_info *fbi, basic_block bb)
618 gcc_checking_assert (fbi);
619 return &fbi->bb_infos[bb->index];
622 /* Structure to be passed in between detect_type_change and
623 check_stmt_for_type_change. */
625 struct prop_type_change_info
627 /* Offset into the object where there is the virtual method pointer we are
628 looking for. */
629 HOST_WIDE_INT offset;
630 /* The declaration or SSA_NAME pointer of the base that we are checking for
631 type change. */
632 tree object;
633 /* Set to true if dynamic type change has been detected. */
634 bool type_maybe_changed;
637 /* Return true if STMT can modify a virtual method table pointer.
639 This function makes special assumptions about both constructors and
640 destructors which are all the functions that are allowed to alter the VMT
641 pointers. It assumes that destructors begin with assignment into all VMT
642 pointers and that constructors essentially look in the following way:
644 1) The very first thing they do is that they call constructors of ancestor
645 sub-objects that have them.
647 2) Then VMT pointers of this and all its ancestors is set to new values
648 corresponding to the type corresponding to the constructor.
650 3) Only afterwards, other stuff such as constructor of member sub-objects
651 and the code written by the user is run. Only this may include calling
652 virtual functions, directly or indirectly.
654 There is no way to call a constructor of an ancestor sub-object in any
655 other way.
657 This means that we do not have to care whether constructors get the correct
658 type information because they will always change it (in fact, if we define
659 the type to be given by the VMT pointer, it is undefined).
661 The most important fact to derive from the above is that if, for some
662 statement in the section 3, we try to detect whether the dynamic type has
663 changed, we can safely ignore all calls as we examine the function body
664 backwards until we reach statements in section 2 because these calls cannot
665 be ancestor constructors or destructors (if the input is not bogus) and so
666 do not change the dynamic type (this holds true only for automatically
667 allocated objects but at the moment we devirtualize only these). We then
668 must detect that statements in section 2 change the dynamic type and can try
669 to derive the new type. That is enough and we can stop, we will never see
670 the calls into constructors of sub-objects in this code. Therefore we can
671 safely ignore all call statements that we traverse.
674 static bool
675 stmt_may_be_vtbl_ptr_store (gimple *stmt)
677 if (is_gimple_call (stmt))
678 return false;
679 if (gimple_clobber_p (stmt))
680 return false;
681 else if (is_gimple_assign (stmt))
683 tree lhs = gimple_assign_lhs (stmt);
685 if (!AGGREGATE_TYPE_P (TREE_TYPE (lhs)))
687 if (flag_strict_aliasing
688 && !POINTER_TYPE_P (TREE_TYPE (lhs)))
689 return false;
691 if (TREE_CODE (lhs) == COMPONENT_REF
692 && !DECL_VIRTUAL_P (TREE_OPERAND (lhs, 1)))
693 return false;
694 /* In the future we might want to use get_ref_base_and_extent to find
695 if there is a field corresponding to the offset and if so, proceed
696 almost like if it was a component ref. */
699 return true;
702 /* Callback of walk_aliased_vdefs and a helper function for detect_type_change
703 to check whether a particular statement may modify the virtual table
704 pointerIt stores its result into DATA, which points to a
705 prop_type_change_info structure. */
707 static bool
708 check_stmt_for_type_change (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
710 gimple *stmt = SSA_NAME_DEF_STMT (vdef);
711 struct prop_type_change_info *tci = (struct prop_type_change_info *) data;
713 if (stmt_may_be_vtbl_ptr_store (stmt))
715 tci->type_maybe_changed = true;
716 return true;
718 else
719 return false;
722 /* See if ARG is PARAM_DECl describing instance passed by pointer
723 or reference in FUNCTION. Return false if the dynamic type may change
724 in between beggining of the function until CALL is invoked.
726 Generally functions are not allowed to change type of such instances,
727 but they call destructors. We assume that methods cannot destroy the THIS
728 pointer. Also as a special cases, constructor and destructors may change
729 type of the THIS pointer. */
731 static bool
732 param_type_may_change_p (tree function, tree arg, gimple *call)
734 /* Pure functions cannot do any changes on the dynamic type;
735 that require writting to memory. */
736 if (flags_from_decl_or_type (function) & (ECF_PURE | ECF_CONST))
737 return false;
738 /* We need to check if we are within inlined consturctor
739 or destructor (ideally we would have way to check that the
740 inline cdtor is actually working on ARG, but we don't have
741 easy tie on this, so punt on all non-pure cdtors.
742 We may also record the types of cdtors and once we know type
743 of the instance match them.
745 Also code unification optimizations may merge calls from
746 different blocks making return values unreliable. So
747 do nothing during late optimization. */
748 if (DECL_STRUCT_FUNCTION (function)->after_inlining)
749 return true;
750 if (TREE_CODE (arg) == SSA_NAME
751 && SSA_NAME_IS_DEFAULT_DEF (arg)
752 && TREE_CODE (SSA_NAME_VAR (arg)) == PARM_DECL)
754 /* Normal (non-THIS) argument. */
755 if ((SSA_NAME_VAR (arg) != DECL_ARGUMENTS (function)
756 || TREE_CODE (TREE_TYPE (function)) != METHOD_TYPE)
757 /* THIS pointer of an method - here we want to watch constructors
758 and destructors as those definitely may change the dynamic
759 type. */
760 || (TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE
761 && !DECL_CXX_CONSTRUCTOR_P (function)
762 && !DECL_CXX_DESTRUCTOR_P (function)
763 && (SSA_NAME_VAR (arg) == DECL_ARGUMENTS (function))))
765 /* Walk the inline stack and watch out for ctors/dtors. */
766 for (tree block = gimple_block (call); block && TREE_CODE (block) == BLOCK;
767 block = BLOCK_SUPERCONTEXT (block))
768 if (inlined_polymorphic_ctor_dtor_block_p (block, false))
769 return true;
770 return false;
773 return true;
776 /* Detect whether the dynamic type of ARG of COMP_TYPE has changed (before
777 callsite CALL) by looking for assignments to its virtual table pointer. If
778 it is, return true. ARG is the object itself (not a pointer
779 to it, unless dereferenced). BASE is the base of the memory access as
780 returned by get_ref_base_and_extent, as is the offset.
782 This is helper function for detect_type_change and detect_type_change_ssa
783 that does the heavy work which is usually unnecesary. */
785 static bool
786 detect_type_change_from_memory_writes (ipa_func_body_info *fbi, tree arg,
787 tree base, tree comp_type, gcall *call,
788 HOST_WIDE_INT offset)
790 struct prop_type_change_info tci;
791 ao_ref ao;
793 gcc_checking_assert (DECL_P (arg)
794 || TREE_CODE (arg) == MEM_REF
795 || handled_component_p (arg));
797 comp_type = TYPE_MAIN_VARIANT (comp_type);
799 /* Const calls cannot call virtual methods through VMT and so type changes do
800 not matter. */
801 if (!flag_devirtualize || !gimple_vuse (call)
802 /* Be sure expected_type is polymorphic. */
803 || !comp_type
804 || TREE_CODE (comp_type) != RECORD_TYPE
805 || !TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type))
806 || !BINFO_VTABLE (TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type))))
807 return true;
809 if (fbi->aa_walk_budget == 0)
810 return false;
812 ao_ref_init (&ao, arg);
813 ao.base = base;
814 ao.offset = offset;
815 ao.size = POINTER_SIZE;
816 ao.max_size = ao.size;
818 tci.offset = offset;
819 tci.object = get_base_address (arg);
820 tci.type_maybe_changed = false;
822 int walked
823 = walk_aliased_vdefs (&ao, gimple_vuse (call), check_stmt_for_type_change,
824 &tci, NULL, NULL, fbi->aa_walk_budget);
825 if (walked >= 0)
826 fbi->aa_walk_budget -= walked;
827 else
828 fbi->aa_walk_budget = 0;
830 if (walked >= 0 && !tci.type_maybe_changed)
831 return false;
833 return true;
836 /* Detect whether the dynamic type of ARG of COMP_TYPE may have changed.
837 If it is, return true. ARG is the object itself (not a pointer
838 to it, unless dereferenced). BASE is the base of the memory access as
839 returned by get_ref_base_and_extent, as is the offset. */
841 static bool
842 detect_type_change (ipa_func_body_info *fbi, tree arg, tree base,
843 tree comp_type, gcall *call,
844 HOST_WIDE_INT offset)
846 if (!flag_devirtualize)
847 return false;
849 if (TREE_CODE (base) == MEM_REF
850 && !param_type_may_change_p (current_function_decl,
851 TREE_OPERAND (base, 0),
852 call))
853 return false;
854 return detect_type_change_from_memory_writes (fbi, arg, base, comp_type,
855 call, offset);
858 /* Like detect_type_change but ARG is supposed to be a non-dereferenced pointer
859 SSA name (its dereference will become the base and the offset is assumed to
860 be zero). */
862 static bool
863 detect_type_change_ssa (ipa_func_body_info *fbi, tree arg, tree comp_type,
864 gcall *call)
866 gcc_checking_assert (TREE_CODE (arg) == SSA_NAME);
867 if (!flag_devirtualize
868 || !POINTER_TYPE_P (TREE_TYPE (arg)))
869 return false;
871 if (!param_type_may_change_p (current_function_decl, arg, call))
872 return false;
874 arg = build2 (MEM_REF, ptr_type_node, arg,
875 build_int_cst (ptr_type_node, 0));
877 return detect_type_change_from_memory_writes (fbi, arg, arg, comp_type,
878 call, 0);
881 /* Callback of walk_aliased_vdefs. Flags that it has been invoked to the
882 boolean variable pointed to by DATA. */
884 static bool
885 mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
886 void *data)
888 bool *b = (bool *) data;
889 *b = true;
890 return true;
893 /* Find the nearest valid aa status for parameter specified by INDEX that
894 dominates BB. */
896 static struct ipa_param_aa_status *
897 find_dominating_aa_status (struct ipa_func_body_info *fbi, basic_block bb,
898 int index)
900 while (true)
902 bb = get_immediate_dominator (CDI_DOMINATORS, bb);
903 if (!bb)
904 return NULL;
905 struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
906 if (!bi->param_aa_statuses.is_empty ()
907 && bi->param_aa_statuses[index].valid)
908 return &bi->param_aa_statuses[index];
912 /* Get AA status structure for the given BB and parameter with INDEX. Allocate
913 structures and/or intialize the result with a dominating description as
914 necessary. */
916 static struct ipa_param_aa_status *
917 parm_bb_aa_status_for_bb (struct ipa_func_body_info *fbi, basic_block bb,
918 int index)
920 gcc_checking_assert (fbi);
921 struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
922 if (bi->param_aa_statuses.is_empty ())
923 bi->param_aa_statuses.safe_grow_cleared (fbi->param_count, true);
924 struct ipa_param_aa_status *paa = &bi->param_aa_statuses[index];
925 if (!paa->valid)
927 gcc_checking_assert (!paa->parm_modified
928 && !paa->ref_modified
929 && !paa->pt_modified);
930 struct ipa_param_aa_status *dom_paa;
931 dom_paa = find_dominating_aa_status (fbi, bb, index);
932 if (dom_paa)
933 *paa = *dom_paa;
934 else
935 paa->valid = true;
938 return paa;
941 /* Return true if a load from a formal parameter PARM_LOAD is known to retrieve
942 a value known not to be modified in this function before reaching the
943 statement STMT. FBI holds information about the function we have so far
944 gathered but do not survive the summary building stage. */
946 static bool
947 parm_preserved_before_stmt_p (struct ipa_func_body_info *fbi, int index,
948 gimple *stmt, tree parm_load)
950 struct ipa_param_aa_status *paa;
951 bool modified = false;
952 ao_ref refd;
954 tree base = get_base_address (parm_load);
955 gcc_assert (TREE_CODE (base) == PARM_DECL);
956 if (TREE_READONLY (base))
957 return true;
959 gcc_checking_assert (fbi);
960 paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (stmt), index);
961 if (paa->parm_modified || fbi->aa_walk_budget == 0)
962 return false;
964 gcc_checking_assert (gimple_vuse (stmt) != NULL_TREE);
965 ao_ref_init (&refd, parm_load);
966 int walked = walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified,
967 &modified, NULL, NULL,
968 fbi->aa_walk_budget);
969 if (walked < 0)
971 modified = true;
972 fbi->aa_walk_budget = 0;
974 else
975 fbi->aa_walk_budget -= walked;
976 if (paa && modified)
977 paa->parm_modified = true;
978 return !modified;
981 /* If STMT is an assignment that loads a value from an parameter declaration,
982 return the index of the parameter in ipa_node_params which has not been
983 modified. Otherwise return -1. */
985 static int
986 load_from_unmodified_param (struct ipa_func_body_info *fbi,
987 vec<ipa_param_descriptor, va_gc> *descriptors,
988 gimple *stmt)
990 int index;
991 tree op1;
993 if (!gimple_assign_single_p (stmt))
994 return -1;
996 op1 = gimple_assign_rhs1 (stmt);
997 if (TREE_CODE (op1) != PARM_DECL)
998 return -1;
1000 index = ipa_get_param_decl_index_1 (descriptors, op1);
1001 if (index < 0
1002 || !parm_preserved_before_stmt_p (fbi, index, stmt, op1))
1003 return -1;
1005 return index;
1008 /* Return true if memory reference REF (which must be a load through parameter
1009 with INDEX) loads data that are known to be unmodified in this function
1010 before reaching statement STMT. */
1012 static bool
1013 parm_ref_data_preserved_p (struct ipa_func_body_info *fbi,
1014 int index, gimple *stmt, tree ref)
1016 struct ipa_param_aa_status *paa;
1017 bool modified = false;
1018 ao_ref refd;
1020 gcc_checking_assert (fbi);
1021 paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (stmt), index);
1022 if (paa->ref_modified || fbi->aa_walk_budget == 0)
1023 return false;
1025 gcc_checking_assert (gimple_vuse (stmt));
1026 ao_ref_init (&refd, ref);
1027 int walked = walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified,
1028 &modified, NULL, NULL,
1029 fbi->aa_walk_budget);
1030 if (walked < 0)
1032 modified = true;
1033 fbi->aa_walk_budget = 0;
1035 else
1036 fbi->aa_walk_budget -= walked;
1037 if (modified)
1038 paa->ref_modified = true;
1039 return !modified;
1042 /* Return true if the data pointed to by PARM (which is a parameter with INDEX)
1043 is known to be unmodified in this function before reaching call statement
1044 CALL into which it is passed. FBI describes the function body. */
1046 static bool
1047 parm_ref_data_pass_through_p (struct ipa_func_body_info *fbi, int index,
1048 gimple *call, tree parm)
1050 bool modified = false;
1051 ao_ref refd;
1053 /* It's unnecessary to calculate anything about memory contnets for a const
1054 function because it is not goin to use it. But do not cache the result
1055 either. Also, no such calculations for non-pointers. */
1056 if (!gimple_vuse (call)
1057 || !POINTER_TYPE_P (TREE_TYPE (parm)))
1058 return false;
1060 struct ipa_param_aa_status *paa = parm_bb_aa_status_for_bb (fbi,
1061 gimple_bb (call),
1062 index);
1063 if (paa->pt_modified || fbi->aa_walk_budget == 0)
1064 return false;
1066 ao_ref_init_from_ptr_and_size (&refd, parm, NULL_TREE);
1067 int walked = walk_aliased_vdefs (&refd, gimple_vuse (call), mark_modified,
1068 &modified, NULL, NULL,
1069 fbi->aa_walk_budget);
1070 if (walked < 0)
1072 fbi->aa_walk_budget = 0;
1073 modified = true;
1075 else
1076 fbi->aa_walk_budget -= walked;
1077 if (modified)
1078 paa->pt_modified = true;
1079 return !modified;
1082 /* Return true if we can prove that OP is a memory reference loading
1083 data from an aggregate passed as a parameter.
1085 The function works in two modes. If GUARANTEED_UNMODIFIED is NULL, it return
1086 false if it cannot prove that the value has not been modified before the
1087 load in STMT. If GUARANTEED_UNMODIFIED is not NULL, it will return true even
1088 if it cannot prove the value has not been modified, in that case it will
1089 store false to *GUARANTEED_UNMODIFIED, otherwise it will store true there.
1091 INFO and PARMS_AINFO describe parameters of the current function (but the
1092 latter can be NULL), STMT is the load statement. If function returns true,
1093 *INDEX_P, *OFFSET_P and *BY_REF is filled with the parameter index, offset
1094 within the aggregate and whether it is a load from a value passed by
1095 reference respectively. */
1097 bool
1098 ipa_load_from_parm_agg (struct ipa_func_body_info *fbi,
1099 vec<ipa_param_descriptor, va_gc> *descriptors,
1100 gimple *stmt, tree op, int *index_p,
1101 HOST_WIDE_INT *offset_p, poly_int64 *size_p,
1102 bool *by_ref_p, bool *guaranteed_unmodified)
1104 int index;
1105 HOST_WIDE_INT size;
1106 bool reverse;
1107 tree base = get_ref_base_and_extent_hwi (op, offset_p, &size, &reverse);
1109 if (!base)
1110 return false;
1112 if (DECL_P (base))
1114 int index = ipa_get_param_decl_index_1 (descriptors, base);
1115 if (index >= 0
1116 && parm_preserved_before_stmt_p (fbi, index, stmt, op))
1118 *index_p = index;
1119 *by_ref_p = false;
1120 if (size_p)
1121 *size_p = size;
1122 if (guaranteed_unmodified)
1123 *guaranteed_unmodified = true;
1124 return true;
1126 return false;
1129 if (TREE_CODE (base) != MEM_REF
1130 || TREE_CODE (TREE_OPERAND (base, 0)) != SSA_NAME
1131 || !integer_zerop (TREE_OPERAND (base, 1)))
1132 return false;
1134 if (SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (base, 0)))
1136 tree parm = SSA_NAME_VAR (TREE_OPERAND (base, 0));
1137 index = ipa_get_param_decl_index_1 (descriptors, parm);
1139 else
1141 /* This branch catches situations where a pointer parameter is not a
1142 gimple register, for example:
1144 void hip7(S*) (struct S * p)
1146 void (*<T2e4>) (struct S *) D.1867;
1147 struct S * p.1;
1149 <bb 2>:
1150 p.1_1 = p;
1151 D.1867_2 = p.1_1->f;
1152 D.1867_2 ();
1153 gdp = &p;
1156 gimple *def = SSA_NAME_DEF_STMT (TREE_OPERAND (base, 0));
1157 index = load_from_unmodified_param (fbi, descriptors, def);
1160 if (index >= 0)
1162 bool data_preserved = parm_ref_data_preserved_p (fbi, index, stmt, op);
1163 if (!data_preserved && !guaranteed_unmodified)
1164 return false;
1166 *index_p = index;
1167 *by_ref_p = true;
1168 if (size_p)
1169 *size_p = size;
1170 if (guaranteed_unmodified)
1171 *guaranteed_unmodified = data_preserved;
1172 return true;
1174 return false;
1177 /* If STMT is an assignment that loads a value from a parameter declaration,
1178 or from an aggregate passed as the parameter either by value or reference,
1179 return the index of the parameter in ipa_node_params. Otherwise return -1.
1181 FBI holds gathered information about the function. INFO describes
1182 parameters of the function, STMT is the assignment statement. If it is a
1183 memory load from an aggregate, *OFFSET_P is filled with offset within the
1184 aggregate, and *BY_REF_P specifies whether the aggregate is passed by
1185 reference. */
1187 static int
1188 load_from_unmodified_param_or_agg (struct ipa_func_body_info *fbi,
1189 class ipa_node_params *info,
1190 gimple *stmt,
1191 HOST_WIDE_INT *offset_p,
1192 bool *by_ref_p)
1194 int index = load_from_unmodified_param (fbi, info->descriptors, stmt);
1195 poly_int64 size;
1197 /* Load value from a parameter declaration. */
1198 if (index >= 0)
1200 *offset_p = -1;
1201 return index;
1204 if (!gimple_assign_load_p (stmt))
1205 return -1;
1207 tree rhs = gimple_assign_rhs1 (stmt);
1209 /* Skip memory reference containing VIEW_CONVERT_EXPR. */
1210 for (tree t = rhs; handled_component_p (t); t = TREE_OPERAND (t, 0))
1211 if (TREE_CODE (t) == VIEW_CONVERT_EXPR)
1212 return -1;
1214 /* Skip memory reference containing bit-field. */
1215 if (TREE_CODE (rhs) == BIT_FIELD_REF
1216 || contains_bitfld_component_ref_p (rhs))
1217 return -1;
1219 if (!ipa_load_from_parm_agg (fbi, info->descriptors, stmt, rhs, &index,
1220 offset_p, &size, by_ref_p))
1221 return -1;
1223 gcc_assert (!maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (rhs))),
1224 size));
1225 if (!*by_ref_p)
1227 tree param_type = ipa_get_type (info, index);
1229 if (!param_type || !AGGREGATE_TYPE_P (param_type))
1230 return -1;
1232 else if (TREE_THIS_VOLATILE (rhs))
1233 return -1;
1235 return index;
1238 /* Walk pointer adjustemnts from OP (such as POINTER_PLUS and ADDR_EXPR)
1239 to find original pointer. Initialize RET to the pointer which results from
1240 the walk.
1241 If offset is known return true and initialize OFFSET_RET. */
1243 bool
1244 unadjusted_ptr_and_unit_offset (tree op, tree *ret, poly_int64 *offset_ret)
1246 poly_int64 offset = 0;
1247 bool offset_known = true;
1248 int i;
1250 for (i = 0; i < param_ipa_jump_function_lookups; i++)
1252 if (TREE_CODE (op) == ADDR_EXPR)
1254 poly_int64 extra_offset = 0;
1255 tree base = get_addr_base_and_unit_offset (TREE_OPERAND (op, 0),
1256 &offset);
1257 if (!base)
1259 base = get_base_address (TREE_OPERAND (op, 0));
1260 if (TREE_CODE (base) != MEM_REF)
1261 break;
1262 offset_known = false;
1264 else
1266 if (TREE_CODE (base) != MEM_REF)
1267 break;
1268 offset += extra_offset;
1270 op = TREE_OPERAND (base, 0);
1271 if (mem_ref_offset (base).to_shwi (&extra_offset))
1272 offset += extra_offset;
1273 else
1274 offset_known = false;
1276 else if (TREE_CODE (op) == SSA_NAME
1277 && !SSA_NAME_IS_DEFAULT_DEF (op))
1279 gimple *pstmt = SSA_NAME_DEF_STMT (op);
1281 if (gimple_assign_single_p (pstmt))
1282 op = gimple_assign_rhs1 (pstmt);
1283 else if (is_gimple_assign (pstmt)
1284 && gimple_assign_rhs_code (pstmt) == POINTER_PLUS_EXPR)
1286 poly_int64 extra_offset = 0;
1287 if (ptrdiff_tree_p (gimple_assign_rhs2 (pstmt),
1288 &extra_offset))
1289 offset += extra_offset;
1290 else
1291 offset_known = false;
1292 op = gimple_assign_rhs1 (pstmt);
1294 else
1295 break;
1297 else
1298 break;
1300 *ret = op;
1301 *offset_ret = offset;
1302 return offset_known;
1305 /* Given that an actual argument is an SSA_NAME (given in NAME) and is a result
1306 of an assignment statement STMT, try to determine whether we are actually
1307 handling any of the following cases and construct an appropriate jump
1308 function into JFUNC if so:
1310 1) The passed value is loaded from a formal parameter which is not a gimple
1311 register (most probably because it is addressable, the value has to be
1312 scalar) and we can guarantee the value has not changed. This case can
1313 therefore be described by a simple pass-through jump function. For example:
1315 foo (int a)
1317 int a.0;
1319 a.0_2 = a;
1320 bar (a.0_2);
1322 2) The passed value can be described by a simple arithmetic pass-through
1323 jump function. E.g.
1325 foo (int a)
1327 int D.2064;
1329 D.2064_4 = a.1(D) + 4;
1330 bar (D.2064_4);
1332 This case can also occur in combination of the previous one, e.g.:
1334 foo (int a, int z)
1336 int a.0;
1337 int D.2064;
1339 a.0_3 = a;
1340 D.2064_4 = a.0_3 + 4;
1341 foo (D.2064_4);
1343 3) The passed value is an address of an object within another one (which
1344 also passed by reference). Such situations are described by an ancestor
1345 jump function and describe situations such as:
1347 B::foo() (struct B * const this)
1349 struct A * D.1845;
1351 D.1845_2 = &this_1(D)->D.1748;
1352 A::bar (D.1845_2);
1354 INFO is the structure describing individual parameters access different
1355 stages of IPA optimizations. PARMS_AINFO contains the information that is
1356 only needed for intraprocedural analysis. */
1358 static void
1359 compute_complex_assign_jump_func (struct ipa_func_body_info *fbi,
1360 class ipa_node_params *info,
1361 struct ipa_jump_func *jfunc,
1362 gcall *call, gimple *stmt, tree name,
1363 tree param_type)
1365 HOST_WIDE_INT offset, size;
1366 tree op1, tc_ssa, base, ssa;
1367 bool reverse;
1368 int index;
1370 op1 = gimple_assign_rhs1 (stmt);
1372 if (TREE_CODE (op1) == SSA_NAME)
1374 if (SSA_NAME_IS_DEFAULT_DEF (op1))
1375 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (op1));
1376 else
1377 index = load_from_unmodified_param (fbi, info->descriptors,
1378 SSA_NAME_DEF_STMT (op1));
1379 tc_ssa = op1;
1381 else
1383 index = load_from_unmodified_param (fbi, info->descriptors, stmt);
1384 tc_ssa = gimple_assign_lhs (stmt);
1387 if (index >= 0)
1389 switch (gimple_assign_rhs_class (stmt))
1391 case GIMPLE_BINARY_RHS:
1393 tree op2 = gimple_assign_rhs2 (stmt);
1394 if (!is_gimple_ip_invariant (op2)
1395 || ((TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))
1396 != tcc_comparison)
1397 && !useless_type_conversion_p (TREE_TYPE (name),
1398 TREE_TYPE (op1))))
1399 return;
1401 ipa_set_jf_arith_pass_through (jfunc, index, op2,
1402 gimple_assign_rhs_code (stmt));
1403 break;
1405 case GIMPLE_SINGLE_RHS:
1407 bool agg_p = parm_ref_data_pass_through_p (fbi, index, call,
1408 tc_ssa);
1409 ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
1410 break;
1412 case GIMPLE_UNARY_RHS:
1413 if (!CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt)))
1414 ipa_set_jf_unary_pass_through (jfunc, index,
1415 gimple_assign_rhs_code (stmt));
1416 default:;
1418 return;
1421 if (TREE_CODE (op1) != ADDR_EXPR)
1422 return;
1423 op1 = TREE_OPERAND (op1, 0);
1424 if (TREE_CODE (TREE_TYPE (op1)) != RECORD_TYPE)
1425 return;
1426 base = get_ref_base_and_extent_hwi (op1, &offset, &size, &reverse);
1427 offset_int mem_offset;
1428 if (!base
1429 || TREE_CODE (base) != MEM_REF
1430 || !mem_ref_offset (base).is_constant (&mem_offset))
1431 return;
1432 offset += mem_offset.to_short_addr () * BITS_PER_UNIT;
1433 ssa = TREE_OPERAND (base, 0);
1434 if (TREE_CODE (ssa) != SSA_NAME
1435 || !SSA_NAME_IS_DEFAULT_DEF (ssa)
1436 || offset < 0)
1437 return;
1439 /* Dynamic types are changed in constructors and destructors. */
1440 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (ssa));
1441 if (index >= 0 && param_type && POINTER_TYPE_P (param_type))
1442 ipa_set_ancestor_jf (jfunc, offset, index,
1443 parm_ref_data_pass_through_p (fbi, index, call, ssa));
1446 /* Extract the base, offset and MEM_REF expression from a statement ASSIGN if
1447 it looks like:
1449 iftmp.1_3 = &obj_2(D)->D.1762;
1451 The base of the MEM_REF must be a default definition SSA NAME of a
1452 parameter. Return NULL_TREE if it looks otherwise. If case of success, the
1453 whole MEM_REF expression is returned and the offset calculated from any
1454 handled components and the MEM_REF itself is stored into *OFFSET. The whole
1455 RHS stripped off the ADDR_EXPR is stored into *OBJ_P. */
1457 static tree
1458 get_ancestor_addr_info (gimple *assign, tree *obj_p, HOST_WIDE_INT *offset)
1460 HOST_WIDE_INT size;
1461 tree expr, parm, obj;
1462 bool reverse;
1464 if (!gimple_assign_single_p (assign))
1465 return NULL_TREE;
1466 expr = gimple_assign_rhs1 (assign);
1468 if (TREE_CODE (expr) != ADDR_EXPR)
1469 return NULL_TREE;
1470 expr = TREE_OPERAND (expr, 0);
1471 obj = expr;
1472 expr = get_ref_base_and_extent_hwi (expr, offset, &size, &reverse);
1474 offset_int mem_offset;
1475 if (!expr
1476 || TREE_CODE (expr) != MEM_REF
1477 || !mem_ref_offset (expr).is_constant (&mem_offset))
1478 return NULL_TREE;
1479 parm = TREE_OPERAND (expr, 0);
1480 if (TREE_CODE (parm) != SSA_NAME
1481 || !SSA_NAME_IS_DEFAULT_DEF (parm)
1482 || TREE_CODE (SSA_NAME_VAR (parm)) != PARM_DECL)
1483 return NULL_TREE;
1485 *offset += mem_offset.to_short_addr () * BITS_PER_UNIT;
1486 *obj_p = obj;
1487 return expr;
1491 /* Given that an actual argument is an SSA_NAME that is a result of a phi
1492 statement PHI, try to find out whether NAME is in fact a
1493 multiple-inheritance typecast from a descendant into an ancestor of a formal
1494 parameter and thus can be described by an ancestor jump function and if so,
1495 write the appropriate function into JFUNC.
1497 Essentially we want to match the following pattern:
1499 if (obj_2(D) != 0B)
1500 goto <bb 3>;
1501 else
1502 goto <bb 4>;
1504 <bb 3>:
1505 iftmp.1_3 = &obj_2(D)->D.1762;
1507 <bb 4>:
1508 # iftmp.1_1 = PHI <iftmp.1_3(3), 0B(2)>
1509 D.1879_6 = middleman_1 (iftmp.1_1, i_5(D));
1510 return D.1879_6; */
1512 static void
1513 compute_complex_ancestor_jump_func (struct ipa_func_body_info *fbi,
1514 class ipa_node_params *info,
1515 struct ipa_jump_func *jfunc,
1516 gcall *call, gphi *phi)
1518 HOST_WIDE_INT offset;
1519 gimple *assign, *cond;
1520 basic_block phi_bb, assign_bb, cond_bb;
1521 tree tmp, parm, expr, obj;
1522 int index, i;
1524 if (gimple_phi_num_args (phi) != 2)
1525 return;
1527 if (integer_zerop (PHI_ARG_DEF (phi, 1)))
1528 tmp = PHI_ARG_DEF (phi, 0);
1529 else if (integer_zerop (PHI_ARG_DEF (phi, 0)))
1530 tmp = PHI_ARG_DEF (phi, 1);
1531 else
1532 return;
1533 if (TREE_CODE (tmp) != SSA_NAME
1534 || SSA_NAME_IS_DEFAULT_DEF (tmp)
1535 || !POINTER_TYPE_P (TREE_TYPE (tmp))
1536 || TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) != RECORD_TYPE)
1537 return;
1539 assign = SSA_NAME_DEF_STMT (tmp);
1540 assign_bb = gimple_bb (assign);
1541 if (!single_pred_p (assign_bb))
1542 return;
1543 expr = get_ancestor_addr_info (assign, &obj, &offset);
1544 if (!expr)
1545 return;
1546 parm = TREE_OPERAND (expr, 0);
1547 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (parm));
1548 if (index < 0)
1549 return;
1551 cond_bb = single_pred (assign_bb);
1552 cond = last_stmt (cond_bb);
1553 if (!cond
1554 || gimple_code (cond) != GIMPLE_COND
1555 || gimple_cond_code (cond) != NE_EXPR
1556 || gimple_cond_lhs (cond) != parm
1557 || !integer_zerop (gimple_cond_rhs (cond)))
1558 return;
1560 phi_bb = gimple_bb (phi);
1561 for (i = 0; i < 2; i++)
1563 basic_block pred = EDGE_PRED (phi_bb, i)->src;
1564 if (pred != assign_bb && pred != cond_bb)
1565 return;
1568 ipa_set_ancestor_jf (jfunc, offset, index,
1569 parm_ref_data_pass_through_p (fbi, index, call, parm));
1572 /* Inspect the given TYPE and return true iff it has the same structure (the
1573 same number of fields of the same types) as a C++ member pointer. If
1574 METHOD_PTR and DELTA are non-NULL, store the trees representing the
1575 corresponding fields there. */
1577 static bool
1578 type_like_member_ptr_p (tree type, tree *method_ptr, tree *delta)
1580 tree fld;
1582 if (TREE_CODE (type) != RECORD_TYPE)
1583 return false;
1585 fld = TYPE_FIELDS (type);
1586 if (!fld || !POINTER_TYPE_P (TREE_TYPE (fld))
1587 || TREE_CODE (TREE_TYPE (TREE_TYPE (fld))) != METHOD_TYPE
1588 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
1589 return false;
1591 if (method_ptr)
1592 *method_ptr = fld;
1594 fld = DECL_CHAIN (fld);
1595 if (!fld || INTEGRAL_TYPE_P (fld)
1596 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
1597 return false;
1598 if (delta)
1599 *delta = fld;
1601 if (DECL_CHAIN (fld))
1602 return false;
1604 return true;
1607 /* If RHS is an SSA_NAME and it is defined by a simple copy assign statement,
1608 return the rhs of its defining statement, and this statement is stored in
1609 *RHS_STMT. Otherwise return RHS as it is. */
1611 static inline tree
1612 get_ssa_def_if_simple_copy (tree rhs, gimple **rhs_stmt)
1614 while (TREE_CODE (rhs) == SSA_NAME && !SSA_NAME_IS_DEFAULT_DEF (rhs))
1616 gimple *def_stmt = SSA_NAME_DEF_STMT (rhs);
1618 if (gimple_assign_single_p (def_stmt))
1619 rhs = gimple_assign_rhs1 (def_stmt);
1620 else
1621 break;
1622 *rhs_stmt = def_stmt;
1624 return rhs;
1627 /* Simple linked list, describing contents of an aggregate before call. */
1629 struct ipa_known_agg_contents_list
1631 /* Offset and size of the described part of the aggregate. */
1632 HOST_WIDE_INT offset, size;
1634 /* Type of the described part of the aggregate. */
1635 tree type;
1637 /* Known constant value or jump function data describing contents. */
1638 struct ipa_load_agg_data value;
1640 /* Pointer to the next structure in the list. */
1641 struct ipa_known_agg_contents_list *next;
1644 /* Add an aggregate content item into a linked list of
1645 ipa_known_agg_contents_list structure, in which all elements
1646 are sorted ascendingly by offset. */
1648 static inline void
1649 add_to_agg_contents_list (struct ipa_known_agg_contents_list **plist,
1650 struct ipa_known_agg_contents_list *item)
1652 struct ipa_known_agg_contents_list *list = *plist;
1654 for (; list; list = list->next)
1656 if (list->offset >= item->offset)
1657 break;
1659 plist = &list->next;
1662 item->next = list;
1663 *plist = item;
1666 /* Check whether a given aggregate content is clobbered by certain element in
1667 a linked list of ipa_known_agg_contents_list. */
1669 static inline bool
1670 clobber_by_agg_contents_list_p (struct ipa_known_agg_contents_list *list,
1671 struct ipa_known_agg_contents_list *item)
1673 for (; list; list = list->next)
1675 if (list->offset >= item->offset)
1676 return list->offset < item->offset + item->size;
1678 if (list->offset + list->size > item->offset)
1679 return true;
1682 return false;
1685 /* Build aggregate jump function from LIST, assuming there are exactly
1686 VALUE_COUNT entries there and that offset of the passed argument
1687 is ARG_OFFSET and store it into JFUNC. */
1689 static void
1690 build_agg_jump_func_from_list (struct ipa_known_agg_contents_list *list,
1691 int value_count, HOST_WIDE_INT arg_offset,
1692 struct ipa_jump_func *jfunc)
1694 vec_safe_reserve (jfunc->agg.items, value_count, true);
1695 for (; list; list = list->next)
1697 struct ipa_agg_jf_item item;
1698 tree operand = list->value.pass_through.operand;
1700 if (list->value.pass_through.formal_id >= 0)
1702 /* Content value is derived from some formal paramerter. */
1703 if (list->value.offset >= 0)
1704 item.jftype = IPA_JF_LOAD_AGG;
1705 else
1706 item.jftype = IPA_JF_PASS_THROUGH;
1708 item.value.load_agg = list->value;
1709 if (operand)
1710 item.value.pass_through.operand
1711 = unshare_expr_without_location (operand);
1713 else if (operand)
1715 /* Content value is known constant. */
1716 item.jftype = IPA_JF_CONST;
1717 item.value.constant = unshare_expr_without_location (operand);
1719 else
1720 continue;
1722 item.type = list->type;
1723 gcc_assert (tree_to_shwi (TYPE_SIZE (list->type)) == list->size);
1725 item.offset = list->offset - arg_offset;
1726 gcc_assert ((item.offset % BITS_PER_UNIT) == 0);
1728 jfunc->agg.items->quick_push (item);
1732 /* Given an assignment statement STMT, try to collect information into
1733 AGG_VALUE that will be used to construct jump function for RHS of the
1734 assignment, from which content value of an aggregate part comes.
1736 Besides constant and simple pass-through jump functions, also try to
1737 identify whether it matches the following pattern that can be described by
1738 a load-value-from-aggregate jump function, which is a derivative of simple
1739 pass-through jump function.
1741 foo (int *p)
1745 *(q_5 + 4) = *(p_3(D) + 28) op 1;
1746 bar (q_5);
1749 Here IPA_LOAD_AGG_DATA data structure is informative enough to describe
1750 constant, simple pass-through and load-vale-from-aggregate. If value
1751 is constant, it will be kept in field OPERAND, and field FORMAL_ID is
1752 set to -1. For simple pass-through and load-value-from-aggregate, field
1753 FORMAL_ID specifies the related formal parameter index, and field
1754 OFFSET can be used to distinguish them, -1 means simple pass-through,
1755 otherwise means load-value-from-aggregate. */
1757 static void
1758 analyze_agg_content_value (struct ipa_func_body_info *fbi,
1759 struct ipa_load_agg_data *agg_value,
1760 gimple *stmt)
1762 tree lhs = gimple_assign_lhs (stmt);
1763 tree rhs1 = gimple_assign_rhs1 (stmt);
1764 enum tree_code code;
1765 int index = -1;
1767 /* Initialize jump function data for the aggregate part. */
1768 memset (agg_value, 0, sizeof (*agg_value));
1769 agg_value->pass_through.operation = NOP_EXPR;
1770 agg_value->pass_through.formal_id = -1;
1771 agg_value->offset = -1;
1773 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs)) /* TODO: Support aggregate type. */
1774 || TREE_THIS_VOLATILE (lhs)
1775 || TREE_CODE (lhs) == BIT_FIELD_REF
1776 || contains_bitfld_component_ref_p (lhs))
1777 return;
1779 /* Skip SSA copies. */
1780 while (gimple_assign_rhs_class (stmt) == GIMPLE_SINGLE_RHS)
1782 if (TREE_CODE (rhs1) != SSA_NAME || SSA_NAME_IS_DEFAULT_DEF (rhs1))
1783 break;
1785 stmt = SSA_NAME_DEF_STMT (rhs1);
1786 if (!is_gimple_assign (stmt))
1787 break;
1789 rhs1 = gimple_assign_rhs1 (stmt);
1792 if (gphi *phi = dyn_cast<gphi *> (stmt))
1794 /* Also special case like the following (a is a formal parameter):
1796 _12 = *a_11(D).dim[0].stride;
1798 # iftmp.22_9 = PHI <_12(2), 1(3)>
1800 parm.6.dim[0].stride = iftmp.22_9;
1802 __x_MOD_foo (&parm.6, b_31(D));
1804 The aggregate function describing parm.6.dim[0].stride is encoded as a
1805 PASS-THROUGH jump function with ASSERT_EXPR operation whith operand 1
1806 (the constant from the PHI node). */
1808 if (gimple_phi_num_args (phi) != 2)
1809 return;
1810 tree arg0 = gimple_phi_arg_def (phi, 0);
1811 tree arg1 = gimple_phi_arg_def (phi, 1);
1812 tree operand;
1814 if (is_gimple_ip_invariant (arg1))
1816 operand = arg1;
1817 rhs1 = arg0;
1819 else if (is_gimple_ip_invariant (arg0))
1821 operand = arg0;
1822 rhs1 = arg1;
1824 else
1825 return;
1827 rhs1 = get_ssa_def_if_simple_copy (rhs1, &stmt);
1828 if (!is_gimple_assign (stmt))
1829 return;
1831 code = ASSERT_EXPR;
1832 agg_value->pass_through.operand = operand;
1834 else if (is_gimple_assign (stmt))
1836 code = gimple_assign_rhs_code (stmt);
1837 switch (gimple_assign_rhs_class (stmt))
1839 case GIMPLE_SINGLE_RHS:
1840 if (is_gimple_ip_invariant (rhs1))
1842 agg_value->pass_through.operand = rhs1;
1843 return;
1845 code = NOP_EXPR;
1846 break;
1848 case GIMPLE_UNARY_RHS:
1849 /* NOTE: A GIMPLE_UNARY_RHS operation might not be tcc_unary
1850 (truth_not_expr is example), GIMPLE_BINARY_RHS does not imply
1851 tcc_binary, this subtleness is somewhat misleading.
1853 Since tcc_unary is widely used in IPA-CP code to check an operation
1854 with one operand, here we only allow tc_unary operation to avoid
1855 possible problem. Then we can use (opclass == tc_unary) or not to
1856 distinguish unary and binary. */
1857 if (TREE_CODE_CLASS (code) != tcc_unary || CONVERT_EXPR_CODE_P (code))
1858 return;
1860 rhs1 = get_ssa_def_if_simple_copy (rhs1, &stmt);
1861 break;
1863 case GIMPLE_BINARY_RHS:
1865 gimple *rhs1_stmt = stmt;
1866 gimple *rhs2_stmt = stmt;
1867 tree rhs2 = gimple_assign_rhs2 (stmt);
1869 rhs1 = get_ssa_def_if_simple_copy (rhs1, &rhs1_stmt);
1870 rhs2 = get_ssa_def_if_simple_copy (rhs2, &rhs2_stmt);
1872 if (is_gimple_ip_invariant (rhs2))
1874 agg_value->pass_through.operand = rhs2;
1875 stmt = rhs1_stmt;
1877 else if (is_gimple_ip_invariant (rhs1))
1879 if (TREE_CODE_CLASS (code) == tcc_comparison)
1880 code = swap_tree_comparison (code);
1881 else if (!commutative_tree_code (code))
1882 return;
1884 agg_value->pass_through.operand = rhs1;
1885 stmt = rhs2_stmt;
1886 rhs1 = rhs2;
1888 else
1889 return;
1891 if (TREE_CODE_CLASS (code) != tcc_comparison
1892 && !useless_type_conversion_p (TREE_TYPE (lhs),
1893 TREE_TYPE (rhs1)))
1894 return;
1896 break;
1898 default:
1899 return;
1902 else
1903 return;
1905 if (TREE_CODE (rhs1) != SSA_NAME)
1906 index = load_from_unmodified_param_or_agg (fbi, fbi->info, stmt,
1907 &agg_value->offset,
1908 &agg_value->by_ref);
1909 else if (SSA_NAME_IS_DEFAULT_DEF (rhs1))
1910 index = ipa_get_param_decl_index (fbi->info, SSA_NAME_VAR (rhs1));
1912 if (index >= 0)
1914 if (agg_value->offset >= 0)
1915 agg_value->type = TREE_TYPE (rhs1);
1916 agg_value->pass_through.formal_id = index;
1917 agg_value->pass_through.operation = code;
1919 else
1920 agg_value->pass_through.operand = NULL_TREE;
1923 /* If STMT is a memory store to the object whose address is BASE, extract
1924 information (offset, size, and value) into CONTENT, and return true,
1925 otherwise we conservatively assume the whole object is modified with
1926 unknown content, and return false. CHECK_REF means that access to object
1927 is expected to be in form of MEM_REF expression. */
1929 static bool
1930 extract_mem_content (struct ipa_func_body_info *fbi,
1931 gimple *stmt, tree base, bool check_ref,
1932 struct ipa_known_agg_contents_list *content)
1934 HOST_WIDE_INT lhs_offset, lhs_size;
1935 bool reverse;
1937 if (!is_gimple_assign (stmt))
1938 return false;
1940 tree lhs = gimple_assign_lhs (stmt);
1941 tree lhs_base = get_ref_base_and_extent_hwi (lhs, &lhs_offset, &lhs_size,
1942 &reverse);
1943 if (!lhs_base)
1944 return false;
1946 if (check_ref)
1948 if (TREE_CODE (lhs_base) != MEM_REF
1949 || TREE_OPERAND (lhs_base, 0) != base
1950 || !integer_zerop (TREE_OPERAND (lhs_base, 1)))
1951 return false;
1953 else if (lhs_base != base)
1954 return false;
1956 content->offset = lhs_offset;
1957 content->size = lhs_size;
1958 content->type = TREE_TYPE (lhs);
1959 content->next = NULL;
1961 analyze_agg_content_value (fbi, &content->value, stmt);
1962 return true;
1965 /* Traverse statements from CALL backwards, scanning whether an aggregate given
1966 in ARG is filled in constants or values that are derived from caller's
1967 formal parameter in the way described by some kinds of jump functions. FBI
1968 is the context of the caller function for interprocedural analysis. ARG can
1969 either be an aggregate expression or a pointer to an aggregate. ARG_TYPE is
1970 the type of the aggregate, JFUNC is the jump function for the aggregate. */
1972 static void
1973 determine_known_aggregate_parts (struct ipa_func_body_info *fbi,
1974 gcall *call, tree arg,
1975 tree arg_type,
1976 struct ipa_jump_func *jfunc)
1978 struct ipa_known_agg_contents_list *list = NULL, *all_list = NULL;
1979 bitmap visited = NULL;
1980 int item_count = 0, value_count = 0;
1981 HOST_WIDE_INT arg_offset, arg_size;
1982 tree arg_base;
1983 bool check_ref, by_ref;
1984 ao_ref r;
1985 int max_agg_items = opt_for_fn (fbi->node->decl, param_ipa_max_agg_items);
1987 if (max_agg_items == 0)
1988 return;
1990 /* The function operates in three stages. First, we prepare check_ref, r,
1991 arg_base and arg_offset based on what is actually passed as an actual
1992 argument. */
1994 if (POINTER_TYPE_P (arg_type))
1996 by_ref = true;
1997 if (TREE_CODE (arg) == SSA_NAME)
1999 tree type_size;
2000 if (!tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (arg_type)))
2001 || !POINTER_TYPE_P (TREE_TYPE (arg)))
2002 return;
2003 check_ref = true;
2004 arg_base = arg;
2005 arg_offset = 0;
2006 type_size = TYPE_SIZE (TREE_TYPE (arg_type));
2007 arg_size = tree_to_uhwi (type_size);
2008 ao_ref_init_from_ptr_and_size (&r, arg_base, NULL_TREE);
2010 else if (TREE_CODE (arg) == ADDR_EXPR)
2012 bool reverse;
2014 arg = TREE_OPERAND (arg, 0);
2015 arg_base = get_ref_base_and_extent_hwi (arg, &arg_offset,
2016 &arg_size, &reverse);
2017 if (!arg_base)
2018 return;
2019 if (DECL_P (arg_base))
2021 check_ref = false;
2022 ao_ref_init (&r, arg_base);
2024 else
2025 return;
2027 else
2028 return;
2030 else
2032 bool reverse;
2034 gcc_checking_assert (AGGREGATE_TYPE_P (TREE_TYPE (arg)));
2036 by_ref = false;
2037 check_ref = false;
2038 arg_base = get_ref_base_and_extent_hwi (arg, &arg_offset,
2039 &arg_size, &reverse);
2040 if (!arg_base)
2041 return;
2043 ao_ref_init (&r, arg);
2046 /* Second stage traverses virtual SSA web backwards starting from the call
2047 statement, only looks at individual dominating virtual operand (its
2048 definition dominates the call), as long as it is confident that content
2049 of the aggregate is affected by definition of the virtual operand, it
2050 builds a sorted linked list of ipa_agg_jf_list describing that. */
2052 for (tree dom_vuse = gimple_vuse (call);
2053 dom_vuse && fbi->aa_walk_budget > 0;)
2055 gimple *stmt = SSA_NAME_DEF_STMT (dom_vuse);
2057 if (gimple_code (stmt) == GIMPLE_PHI)
2059 dom_vuse = get_continuation_for_phi (stmt, &r, true,
2060 fbi->aa_walk_budget,
2061 &visited, false, NULL, NULL);
2062 continue;
2065 fbi->aa_walk_budget--;
2066 if (stmt_may_clobber_ref_p_1 (stmt, &r))
2068 struct ipa_known_agg_contents_list *content
2069 = XALLOCA (struct ipa_known_agg_contents_list);
2071 if (!extract_mem_content (fbi, stmt, arg_base, check_ref, content))
2072 break;
2074 /* Now we get a dominating virtual operand, and need to check
2075 whether its value is clobbered any other dominating one. */
2076 if ((content->value.pass_through.formal_id >= 0
2077 || content->value.pass_through.operand)
2078 && !clobber_by_agg_contents_list_p (all_list, content))
2080 struct ipa_known_agg_contents_list *copy
2081 = XALLOCA (struct ipa_known_agg_contents_list);
2083 /* Add to the list consisting of only dominating virtual
2084 operands, whose definitions can finally reach the call. */
2085 add_to_agg_contents_list (&list, (*copy = *content, copy));
2087 if (++value_count == max_agg_items)
2088 break;
2091 /* Add to the list consisting of all dominating virtual operands. */
2092 add_to_agg_contents_list (&all_list, content);
2094 if (++item_count == 2 * max_agg_items)
2095 break;
2097 dom_vuse = gimple_vuse (stmt);
2100 if (visited)
2101 BITMAP_FREE (visited);
2103 /* Third stage just goes over the list and creates an appropriate vector of
2104 ipa_agg_jf_item structures out of it, of course only if there are
2105 any meaningful items to begin with. */
2107 if (value_count)
2109 jfunc->agg.by_ref = by_ref;
2110 build_agg_jump_func_from_list (list, value_count, arg_offset, jfunc);
2115 /* Return the Ith param type of callee associated with call graph
2116 edge E. */
2118 tree
2119 ipa_get_callee_param_type (struct cgraph_edge *e, int i)
2121 int n;
2122 tree type = (e->callee
2123 ? TREE_TYPE (e->callee->decl)
2124 : gimple_call_fntype (e->call_stmt));
2125 tree t = TYPE_ARG_TYPES (type);
2127 for (n = 0; n < i; n++)
2129 if (!t)
2130 break;
2131 t = TREE_CHAIN (t);
2133 if (t)
2134 return TREE_VALUE (t);
2135 if (!e->callee)
2136 return NULL;
2137 t = DECL_ARGUMENTS (e->callee->decl);
2138 for (n = 0; n < i; n++)
2140 if (!t)
2141 return NULL;
2142 t = TREE_CHAIN (t);
2144 if (t)
2145 return TREE_TYPE (t);
2146 return NULL;
2149 /* Return ipa_bits with VALUE and MASK values, which can be either a newly
2150 allocated structure or a previously existing one shared with other jump
2151 functions and/or transformation summaries. */
2153 ipa_bits *
2154 ipa_get_ipa_bits_for_value (const widest_int &value, const widest_int &mask)
2156 ipa_bits tmp;
2157 tmp.value = value;
2158 tmp.mask = mask;
2160 ipa_bits **slot = ipa_bits_hash_table->find_slot (&tmp, INSERT);
2161 if (*slot)
2162 return *slot;
2164 ipa_bits *res = ggc_alloc<ipa_bits> ();
2165 res->value = value;
2166 res->mask = mask;
2167 *slot = res;
2169 return res;
2172 /* Assign to JF a pointer to ipa_bits structure with VALUE and MASK. Use hash
2173 table in order to avoid creating multiple same ipa_bits structures. */
2175 static void
2176 ipa_set_jfunc_bits (ipa_jump_func *jf, const widest_int &value,
2177 const widest_int &mask)
2179 jf->bits = ipa_get_ipa_bits_for_value (value, mask);
2182 /* Return a pointer to a value_range just like *TMP, but either find it in
2183 ipa_vr_hash_table or allocate it in GC memory. TMP->equiv must be NULL. */
2185 static value_range *
2186 ipa_get_value_range (value_range *tmp)
2188 value_range **slot = ipa_vr_hash_table->find_slot (tmp, INSERT);
2189 if (*slot)
2190 return *slot;
2192 value_range *vr = new (ggc_alloc<value_range> ()) value_range;
2193 *vr = *tmp;
2194 *slot = vr;
2196 return vr;
2199 /* Return a pointer to a value range consisting of TYPE, MIN, MAX and an empty
2200 equiv set. Use hash table in order to avoid creating multiple same copies of
2201 value_ranges. */
2203 static value_range *
2204 ipa_get_value_range (enum value_range_kind kind, tree min, tree max)
2206 value_range tmp (min, max, kind);
2207 return ipa_get_value_range (&tmp);
2210 /* Assign to JF a pointer to a value_range structure with TYPE, MIN and MAX and
2211 a NULL equiv bitmap. Use hash table in order to avoid creating multiple
2212 same value_range structures. */
2214 static void
2215 ipa_set_jfunc_vr (ipa_jump_func *jf, enum value_range_kind type,
2216 tree min, tree max)
2218 jf->m_vr = ipa_get_value_range (type, min, max);
2221 /* Assign to JF a pointer to a value_range just like TMP but either fetch a
2222 copy from ipa_vr_hash_table or allocate a new on in GC memory. */
2224 static void
2225 ipa_set_jfunc_vr (ipa_jump_func *jf, value_range *tmp)
2227 jf->m_vr = ipa_get_value_range (tmp);
2230 /* Compute jump function for all arguments of callsite CS and insert the
2231 information in the jump_functions array in the ipa_edge_args corresponding
2232 to this callsite. */
2234 static void
2235 ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
2236 struct cgraph_edge *cs)
2238 ipa_node_params *info = ipa_node_params_sum->get (cs->caller);
2239 ipa_edge_args *args = ipa_edge_args_sum->get_create (cs);
2240 gcall *call = cs->call_stmt;
2241 int n, arg_num = gimple_call_num_args (call);
2242 bool useful_context = false;
2243 value_range vr;
2245 if (arg_num == 0 || args->jump_functions)
2246 return;
2247 vec_safe_grow_cleared (args->jump_functions, arg_num, true);
2248 if (flag_devirtualize)
2249 vec_safe_grow_cleared (args->polymorphic_call_contexts, arg_num, true);
2251 if (gimple_call_internal_p (call))
2252 return;
2253 if (ipa_func_spec_opts_forbid_analysis_p (cs->caller))
2254 return;
2256 for (n = 0; n < arg_num; n++)
2258 struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, n);
2259 tree arg = gimple_call_arg (call, n);
2260 tree param_type = ipa_get_callee_param_type (cs, n);
2261 if (flag_devirtualize && POINTER_TYPE_P (TREE_TYPE (arg)))
2263 tree instance;
2264 class ipa_polymorphic_call_context context (cs->caller->decl,
2265 arg, cs->call_stmt,
2266 &instance);
2267 context.get_dynamic_type (instance, arg, NULL, cs->call_stmt,
2268 &fbi->aa_walk_budget);
2269 *ipa_get_ith_polymorhic_call_context (args, n) = context;
2270 if (!context.useless_p ())
2271 useful_context = true;
2274 if (POINTER_TYPE_P (TREE_TYPE (arg)))
2276 bool addr_nonzero = false;
2277 bool strict_overflow = false;
2279 if (TREE_CODE (arg) == SSA_NAME
2280 && param_type
2281 && get_range_query (cfun)->range_of_expr (vr, arg)
2282 && vr.nonzero_p ())
2283 addr_nonzero = true;
2284 else if (tree_single_nonzero_warnv_p (arg, &strict_overflow))
2285 addr_nonzero = true;
2287 if (addr_nonzero)
2289 tree z = build_int_cst (TREE_TYPE (arg), 0);
2290 ipa_set_jfunc_vr (jfunc, VR_ANTI_RANGE, z, z);
2292 else
2293 gcc_assert (!jfunc->m_vr);
2295 else
2297 if (TREE_CODE (arg) == SSA_NAME
2298 && param_type
2299 && get_range_query (cfun)->range_of_expr (vr, arg)
2300 && !vr.undefined_p ())
2302 value_range resvr;
2303 range_fold_unary_expr (&resvr, NOP_EXPR, param_type,
2304 &vr, TREE_TYPE (arg));
2305 if (!resvr.undefined_p () && !resvr.varying_p ())
2306 ipa_set_jfunc_vr (jfunc, &resvr);
2307 else
2308 gcc_assert (!jfunc->m_vr);
2310 else
2311 gcc_assert (!jfunc->m_vr);
2314 if (INTEGRAL_TYPE_P (TREE_TYPE (arg))
2315 && (TREE_CODE (arg) == SSA_NAME || TREE_CODE (arg) == INTEGER_CST))
2317 if (TREE_CODE (arg) == SSA_NAME)
2318 ipa_set_jfunc_bits (jfunc, 0,
2319 widest_int::from (get_nonzero_bits (arg),
2320 TYPE_SIGN (TREE_TYPE (arg))));
2321 else
2322 ipa_set_jfunc_bits (jfunc, wi::to_widest (arg), 0);
2324 else if (POINTER_TYPE_P (TREE_TYPE (arg)))
2326 unsigned HOST_WIDE_INT bitpos;
2327 unsigned align;
2329 get_pointer_alignment_1 (arg, &align, &bitpos);
2330 widest_int mask = wi::bit_and_not
2331 (wi::mask<widest_int> (TYPE_PRECISION (TREE_TYPE (arg)), false),
2332 align / BITS_PER_UNIT - 1);
2333 widest_int value = bitpos / BITS_PER_UNIT;
2334 ipa_set_jfunc_bits (jfunc, value, mask);
2336 else
2337 gcc_assert (!jfunc->bits);
2339 if (is_gimple_ip_invariant (arg)
2340 || (VAR_P (arg)
2341 && is_global_var (arg)
2342 && TREE_READONLY (arg)))
2343 ipa_set_jf_constant (jfunc, arg, cs);
2344 else if (!is_gimple_reg_type (TREE_TYPE (arg))
2345 && TREE_CODE (arg) == PARM_DECL)
2347 int index = ipa_get_param_decl_index (info, arg);
2349 gcc_assert (index >=0);
2350 /* Aggregate passed by value, check for pass-through, otherwise we
2351 will attempt to fill in aggregate contents later in this
2352 for cycle. */
2353 if (parm_preserved_before_stmt_p (fbi, index, call, arg))
2355 ipa_set_jf_simple_pass_through (jfunc, index, false);
2356 continue;
2359 else if (TREE_CODE (arg) == SSA_NAME)
2361 if (SSA_NAME_IS_DEFAULT_DEF (arg))
2363 int index = ipa_get_param_decl_index (info, SSA_NAME_VAR (arg));
2364 if (index >= 0)
2366 bool agg_p;
2367 agg_p = parm_ref_data_pass_through_p (fbi, index, call, arg);
2368 ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
2371 else
2373 gimple *stmt = SSA_NAME_DEF_STMT (arg);
2374 if (is_gimple_assign (stmt))
2375 compute_complex_assign_jump_func (fbi, info, jfunc,
2376 call, stmt, arg, param_type);
2377 else if (gimple_code (stmt) == GIMPLE_PHI)
2378 compute_complex_ancestor_jump_func (fbi, info, jfunc,
2379 call,
2380 as_a <gphi *> (stmt));
2384 /* If ARG is pointer, we cannot use its type to determine the type of aggregate
2385 passed (because type conversions are ignored in gimple). Usually we can
2386 safely get type from function declaration, but in case of K&R prototypes or
2387 variadic functions we can try our luck with type of the pointer passed.
2388 TODO: Since we look for actual initialization of the memory object, we may better
2389 work out the type based on the memory stores we find. */
2390 if (!param_type)
2391 param_type = TREE_TYPE (arg);
2393 if ((jfunc->type != IPA_JF_PASS_THROUGH
2394 || !ipa_get_jf_pass_through_agg_preserved (jfunc))
2395 && (jfunc->type != IPA_JF_ANCESTOR
2396 || !ipa_get_jf_ancestor_agg_preserved (jfunc))
2397 && (AGGREGATE_TYPE_P (TREE_TYPE (arg))
2398 || POINTER_TYPE_P (param_type)))
2399 determine_known_aggregate_parts (fbi, call, arg, param_type, jfunc);
2401 if (!useful_context)
2402 vec_free (args->polymorphic_call_contexts);
2405 /* Compute jump functions for all edges - both direct and indirect - outgoing
2406 from BB. */
2408 static void
2409 ipa_compute_jump_functions_for_bb (struct ipa_func_body_info *fbi, basic_block bb)
2411 struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
2412 int i;
2413 struct cgraph_edge *cs;
2415 FOR_EACH_VEC_ELT_REVERSE (bi->cg_edges, i, cs)
2417 struct cgraph_node *callee = cs->callee;
2419 if (callee)
2421 callee = callee->ultimate_alias_target ();
2422 /* We do not need to bother analyzing calls to unknown functions
2423 unless they may become known during lto/whopr. */
2424 if (!callee->definition && !flag_lto
2425 && !gimple_call_fnspec (cs->call_stmt).known_p ())
2426 continue;
2428 ipa_compute_jump_functions_for_edge (fbi, cs);
2432 /* If STMT looks like a statement loading a value from a member pointer formal
2433 parameter, return that parameter and store the offset of the field to
2434 *OFFSET_P, if it is non-NULL. Otherwise return NULL (but *OFFSET_P still
2435 might be clobbered). If USE_DELTA, then we look for a use of the delta
2436 field rather than the pfn. */
2438 static tree
2439 ipa_get_stmt_member_ptr_load_param (gimple *stmt, bool use_delta,
2440 HOST_WIDE_INT *offset_p)
2442 tree rhs, rec, ref_field, ref_offset, fld, ptr_field, delta_field;
2444 if (!gimple_assign_single_p (stmt))
2445 return NULL_TREE;
2447 rhs = gimple_assign_rhs1 (stmt);
2448 if (TREE_CODE (rhs) == COMPONENT_REF)
2450 ref_field = TREE_OPERAND (rhs, 1);
2451 rhs = TREE_OPERAND (rhs, 0);
2453 else
2454 ref_field = NULL_TREE;
2455 if (TREE_CODE (rhs) != MEM_REF)
2456 return NULL_TREE;
2457 rec = TREE_OPERAND (rhs, 0);
2458 if (TREE_CODE (rec) != ADDR_EXPR)
2459 return NULL_TREE;
2460 rec = TREE_OPERAND (rec, 0);
2461 if (TREE_CODE (rec) != PARM_DECL
2462 || !type_like_member_ptr_p (TREE_TYPE (rec), &ptr_field, &delta_field))
2463 return NULL_TREE;
2464 ref_offset = TREE_OPERAND (rhs, 1);
2466 if (use_delta)
2467 fld = delta_field;
2468 else
2469 fld = ptr_field;
2470 if (offset_p)
2471 *offset_p = int_bit_position (fld);
2473 if (ref_field)
2475 if (integer_nonzerop (ref_offset))
2476 return NULL_TREE;
2477 return ref_field == fld ? rec : NULL_TREE;
2479 else
2480 return tree_int_cst_equal (byte_position (fld), ref_offset) ? rec
2481 : NULL_TREE;
2484 /* Returns true iff T is an SSA_NAME defined by a statement. */
2486 static bool
2487 ipa_is_ssa_with_stmt_def (tree t)
2489 if (TREE_CODE (t) == SSA_NAME
2490 && !SSA_NAME_IS_DEFAULT_DEF (t))
2491 return true;
2492 else
2493 return false;
2496 /* Find the indirect call graph edge corresponding to STMT and mark it as a
2497 call to a parameter number PARAM_INDEX. NODE is the caller. Return the
2498 indirect call graph edge.
2499 If POLYMORPHIC is true record is as a destination of polymorphic call. */
2501 static struct cgraph_edge *
2502 ipa_note_param_call (struct cgraph_node *node, int param_index,
2503 gcall *stmt, bool polymorphic)
2505 struct cgraph_edge *cs;
2507 cs = node->get_edge (stmt);
2508 cs->indirect_info->param_index = param_index;
2509 cs->indirect_info->agg_contents = 0;
2510 cs->indirect_info->member_ptr = 0;
2511 cs->indirect_info->guaranteed_unmodified = 0;
2512 ipa_node_params *info = ipa_node_params_sum->get (node);
2513 ipa_set_param_used_by_indirect_call (info, param_index, true);
2514 if (cs->indirect_info->polymorphic || polymorphic)
2515 ipa_set_param_used_by_polymorphic_call (info, param_index, true);
2516 return cs;
2519 /* Analyze the CALL and examine uses of formal parameters of the caller NODE
2520 (described by INFO). PARMS_AINFO is a pointer to a vector containing
2521 intermediate information about each formal parameter. Currently it checks
2522 whether the call calls a pointer that is a formal parameter and if so, the
2523 parameter is marked with the called flag and an indirect call graph edge
2524 describing the call is created. This is very simple for ordinary pointers
2525 represented in SSA but not-so-nice when it comes to member pointers. The
2526 ugly part of this function does nothing more than trying to match the
2527 pattern of such a call. An example of such a pattern is the gimple dump
2528 below, the call is on the last line:
2530 <bb 2>:
2531 f$__delta_5 = f.__delta;
2532 f$__pfn_24 = f.__pfn;
2535 <bb 2>:
2536 f$__delta_5 = MEM[(struct *)&f];
2537 f$__pfn_24 = MEM[(struct *)&f + 4B];
2539 and a few lines below:
2541 <bb 5>
2542 D.2496_3 = (int) f$__pfn_24;
2543 D.2497_4 = D.2496_3 & 1;
2544 if (D.2497_4 != 0)
2545 goto <bb 3>;
2546 else
2547 goto <bb 4>;
2549 <bb 6>:
2550 D.2500_7 = (unsigned int) f$__delta_5;
2551 D.2501_8 = &S + D.2500_7;
2552 D.2502_9 = (int (*__vtbl_ptr_type) (void) * *) D.2501_8;
2553 D.2503_10 = *D.2502_9;
2554 D.2504_12 = f$__pfn_24 + -1;
2555 D.2505_13 = (unsigned int) D.2504_12;
2556 D.2506_14 = D.2503_10 + D.2505_13;
2557 D.2507_15 = *D.2506_14;
2558 iftmp.11_16 = (String:: *) D.2507_15;
2560 <bb 7>:
2561 # iftmp.11_1 = PHI <iftmp.11_16(3), f$__pfn_24(2)>
2562 D.2500_19 = (unsigned int) f$__delta_5;
2563 D.2508_20 = &S + D.2500_19;
2564 D.2493_21 = iftmp.11_1 (D.2508_20, 4);
2566 Such patterns are results of simple calls to a member pointer:
2568 int doprinting (int (MyString::* f)(int) const)
2570 MyString S ("somestring");
2572 return (S.*f)(4);
2575 Moreover, the function also looks for called pointers loaded from aggregates
2576 passed by value or reference. */
2578 static void
2579 ipa_analyze_indirect_call_uses (struct ipa_func_body_info *fbi, gcall *call,
2580 tree target)
2582 class ipa_node_params *info = fbi->info;
2583 HOST_WIDE_INT offset;
2584 bool by_ref;
2586 if (SSA_NAME_IS_DEFAULT_DEF (target))
2588 tree var = SSA_NAME_VAR (target);
2589 int index = ipa_get_param_decl_index (info, var);
2590 if (index >= 0)
2591 ipa_note_param_call (fbi->node, index, call, false);
2592 return;
2595 int index;
2596 gimple *def = SSA_NAME_DEF_STMT (target);
2597 bool guaranteed_unmodified;
2598 if (gimple_assign_single_p (def)
2599 && ipa_load_from_parm_agg (fbi, info->descriptors, def,
2600 gimple_assign_rhs1 (def), &index, &offset,
2601 NULL, &by_ref, &guaranteed_unmodified))
2603 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
2604 call, false);
2605 cs->indirect_info->offset = offset;
2606 cs->indirect_info->agg_contents = 1;
2607 cs->indirect_info->by_ref = by_ref;
2608 cs->indirect_info->guaranteed_unmodified = guaranteed_unmodified;
2609 return;
2612 /* Now we need to try to match the complex pattern of calling a member
2613 pointer. */
2614 if (gimple_code (def) != GIMPLE_PHI
2615 || gimple_phi_num_args (def) != 2
2616 || !POINTER_TYPE_P (TREE_TYPE (target))
2617 || TREE_CODE (TREE_TYPE (TREE_TYPE (target))) != METHOD_TYPE)
2618 return;
2620 /* First, we need to check whether one of these is a load from a member
2621 pointer that is a parameter to this function. */
2622 tree n1 = PHI_ARG_DEF (def, 0);
2623 tree n2 = PHI_ARG_DEF (def, 1);
2624 if (!ipa_is_ssa_with_stmt_def (n1) || !ipa_is_ssa_with_stmt_def (n2))
2625 return;
2626 gimple *d1 = SSA_NAME_DEF_STMT (n1);
2627 gimple *d2 = SSA_NAME_DEF_STMT (n2);
2629 tree rec;
2630 basic_block bb, virt_bb;
2631 basic_block join = gimple_bb (def);
2632 if ((rec = ipa_get_stmt_member_ptr_load_param (d1, false, &offset)))
2634 if (ipa_get_stmt_member_ptr_load_param (d2, false, NULL))
2635 return;
2637 bb = EDGE_PRED (join, 0)->src;
2638 virt_bb = gimple_bb (d2);
2640 else if ((rec = ipa_get_stmt_member_ptr_load_param (d2, false, &offset)))
2642 bb = EDGE_PRED (join, 1)->src;
2643 virt_bb = gimple_bb (d1);
2645 else
2646 return;
2648 /* Second, we need to check that the basic blocks are laid out in the way
2649 corresponding to the pattern. */
2651 if (!single_pred_p (virt_bb) || !single_succ_p (virt_bb)
2652 || single_pred (virt_bb) != bb
2653 || single_succ (virt_bb) != join)
2654 return;
2656 /* Third, let's see that the branching is done depending on the least
2657 significant bit of the pfn. */
2659 gimple *branch = last_stmt (bb);
2660 if (!branch || gimple_code (branch) != GIMPLE_COND)
2661 return;
2663 if ((gimple_cond_code (branch) != NE_EXPR
2664 && gimple_cond_code (branch) != EQ_EXPR)
2665 || !integer_zerop (gimple_cond_rhs (branch)))
2666 return;
2668 tree cond = gimple_cond_lhs (branch);
2669 if (!ipa_is_ssa_with_stmt_def (cond))
2670 return;
2672 def = SSA_NAME_DEF_STMT (cond);
2673 if (!is_gimple_assign (def)
2674 || gimple_assign_rhs_code (def) != BIT_AND_EXPR
2675 || !integer_onep (gimple_assign_rhs2 (def)))
2676 return;
2678 cond = gimple_assign_rhs1 (def);
2679 if (!ipa_is_ssa_with_stmt_def (cond))
2680 return;
2682 def = SSA_NAME_DEF_STMT (cond);
2684 if (is_gimple_assign (def)
2685 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
2687 cond = gimple_assign_rhs1 (def);
2688 if (!ipa_is_ssa_with_stmt_def (cond))
2689 return;
2690 def = SSA_NAME_DEF_STMT (cond);
2693 tree rec2;
2694 rec2 = ipa_get_stmt_member_ptr_load_param (def,
2695 (TARGET_PTRMEMFUNC_VBIT_LOCATION
2696 == ptrmemfunc_vbit_in_delta),
2697 NULL);
2698 if (rec != rec2)
2699 return;
2701 index = ipa_get_param_decl_index (info, rec);
2702 if (index >= 0
2703 && parm_preserved_before_stmt_p (fbi, index, call, rec))
2705 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
2706 call, false);
2707 cs->indirect_info->offset = offset;
2708 cs->indirect_info->agg_contents = 1;
2709 cs->indirect_info->member_ptr = 1;
2710 cs->indirect_info->guaranteed_unmodified = 1;
2713 return;
2716 /* Analyze a CALL to an OBJ_TYPE_REF which is passed in TARGET and if the
2717 object referenced in the expression is a formal parameter of the caller
2718 FBI->node (described by FBI->info), create a call note for the
2719 statement. */
2721 static void
2722 ipa_analyze_virtual_call_uses (struct ipa_func_body_info *fbi,
2723 gcall *call, tree target)
2725 tree obj = OBJ_TYPE_REF_OBJECT (target);
2726 int index;
2727 HOST_WIDE_INT anc_offset;
2729 if (!flag_devirtualize)
2730 return;
2732 if (TREE_CODE (obj) != SSA_NAME)
2733 return;
2735 class ipa_node_params *info = fbi->info;
2736 if (SSA_NAME_IS_DEFAULT_DEF (obj))
2738 if (TREE_CODE (SSA_NAME_VAR (obj)) != PARM_DECL)
2739 return;
2741 anc_offset = 0;
2742 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (obj));
2743 gcc_assert (index >= 0);
2744 if (detect_type_change_ssa (fbi, obj, obj_type_ref_class (target),
2745 call))
2746 return;
2748 else
2750 gimple *stmt = SSA_NAME_DEF_STMT (obj);
2751 tree expr;
2753 expr = get_ancestor_addr_info (stmt, &obj, &anc_offset);
2754 if (!expr)
2755 return;
2756 index = ipa_get_param_decl_index (info,
2757 SSA_NAME_VAR (TREE_OPERAND (expr, 0)));
2758 gcc_assert (index >= 0);
2759 if (detect_type_change (fbi, obj, expr, obj_type_ref_class (target),
2760 call, anc_offset))
2761 return;
2764 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
2765 call, true);
2766 class cgraph_indirect_call_info *ii = cs->indirect_info;
2767 ii->offset = anc_offset;
2768 ii->otr_token = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target));
2769 ii->otr_type = obj_type_ref_class (target);
2770 ii->polymorphic = 1;
2773 /* Analyze a call statement CALL whether and how it utilizes formal parameters
2774 of the caller (described by INFO). PARMS_AINFO is a pointer to a vector
2775 containing intermediate information about each formal parameter. */
2777 static void
2778 ipa_analyze_call_uses (struct ipa_func_body_info *fbi, gcall *call)
2780 tree target = gimple_call_fn (call);
2782 if (!target
2783 || (TREE_CODE (target) != SSA_NAME
2784 && !virtual_method_call_p (target)))
2785 return;
2787 struct cgraph_edge *cs = fbi->node->get_edge (call);
2788 /* If we previously turned the call into a direct call, there is
2789 no need to analyze. */
2790 if (cs && !cs->indirect_unknown_callee)
2791 return;
2793 if (cs->indirect_info->polymorphic && flag_devirtualize)
2795 tree instance;
2796 tree target = gimple_call_fn (call);
2797 ipa_polymorphic_call_context context (current_function_decl,
2798 target, call, &instance);
2800 gcc_checking_assert (cs->indirect_info->otr_type
2801 == obj_type_ref_class (target));
2802 gcc_checking_assert (cs->indirect_info->otr_token
2803 == tree_to_shwi (OBJ_TYPE_REF_TOKEN (target)));
2805 cs->indirect_info->vptr_changed
2806 = !context.get_dynamic_type (instance,
2807 OBJ_TYPE_REF_OBJECT (target),
2808 obj_type_ref_class (target), call,
2809 &fbi->aa_walk_budget);
2810 cs->indirect_info->context = context;
2813 if (TREE_CODE (target) == SSA_NAME)
2814 ipa_analyze_indirect_call_uses (fbi, call, target);
2815 else if (virtual_method_call_p (target))
2816 ipa_analyze_virtual_call_uses (fbi, call, target);
2820 /* Analyze the call statement STMT with respect to formal parameters (described
2821 in INFO) of caller given by FBI->NODE. Currently it only checks whether
2822 formal parameters are called. */
2824 static void
2825 ipa_analyze_stmt_uses (struct ipa_func_body_info *fbi, gimple *stmt)
2827 if (is_gimple_call (stmt))
2828 ipa_analyze_call_uses (fbi, as_a <gcall *> (stmt));
2831 /* Callback of walk_stmt_load_store_addr_ops for the visit_load.
2832 If OP is a parameter declaration, mark it as used in the info structure
2833 passed in DATA. */
2835 static bool
2836 visit_ref_for_mod_analysis (gimple *, tree op, tree, void *data)
2838 class ipa_node_params *info = (class ipa_node_params *) data;
2840 op = get_base_address (op);
2841 if (op
2842 && TREE_CODE (op) == PARM_DECL)
2844 int index = ipa_get_param_decl_index (info, op);
2845 gcc_assert (index >= 0);
2846 ipa_set_param_used (info, index, true);
2849 return false;
2852 /* Scan the statements in BB and inspect the uses of formal parameters. Store
2853 the findings in various structures of the associated ipa_node_params
2854 structure, such as parameter flags, notes etc. FBI holds various data about
2855 the function being analyzed. */
2857 static void
2858 ipa_analyze_params_uses_in_bb (struct ipa_func_body_info *fbi, basic_block bb)
2860 gimple_stmt_iterator gsi;
2861 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2863 gimple *stmt = gsi_stmt (gsi);
2865 if (is_gimple_debug (stmt))
2866 continue;
2868 ipa_analyze_stmt_uses (fbi, stmt);
2869 walk_stmt_load_store_addr_ops (stmt, fbi->info,
2870 visit_ref_for_mod_analysis,
2871 visit_ref_for_mod_analysis,
2872 visit_ref_for_mod_analysis);
2874 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2875 walk_stmt_load_store_addr_ops (gsi_stmt (gsi), fbi->info,
2876 visit_ref_for_mod_analysis,
2877 visit_ref_for_mod_analysis,
2878 visit_ref_for_mod_analysis);
2881 /* Return true EXPR is a load from a dereference of SSA_NAME NAME. */
2883 static bool
2884 load_from_dereferenced_name (tree expr, tree name)
2886 tree base = get_base_address (expr);
2887 return (TREE_CODE (base) == MEM_REF
2888 && TREE_OPERAND (base, 0) == name);
2891 /* Calculate controlled uses of parameters of NODE. */
2893 static void
2894 ipa_analyze_controlled_uses (struct cgraph_node *node)
2896 ipa_node_params *info = ipa_node_params_sum->get (node);
2898 for (int i = 0; i < ipa_get_param_count (info); i++)
2900 tree parm = ipa_get_param (info, i);
2901 int call_uses = 0;
2902 bool load_dereferenced = false;
2904 /* For SSA regs see if parameter is used. For non-SSA we compute
2905 the flag during modification analysis. */
2906 if (is_gimple_reg (parm))
2908 tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl),
2909 parm);
2910 if (ddef && !has_zero_uses (ddef))
2912 imm_use_iterator imm_iter;
2913 gimple *stmt;
2915 ipa_set_param_used (info, i, true);
2916 FOR_EACH_IMM_USE_STMT (stmt, imm_iter, ddef)
2918 if (is_gimple_debug (stmt))
2919 continue;
2921 int all_stmt_uses = 0;
2922 use_operand_p use_p;
2923 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
2924 all_stmt_uses++;
2926 if (is_gimple_call (stmt))
2928 if (gimple_call_internal_p (stmt))
2930 call_uses = IPA_UNDESCRIBED_USE;
2931 break;
2933 int recognized_stmt_uses;
2934 if (gimple_call_fn (stmt) == ddef)
2935 recognized_stmt_uses = 1;
2936 else
2937 recognized_stmt_uses = 0;
2938 unsigned arg_count = gimple_call_num_args (stmt);
2939 for (unsigned i = 0; i < arg_count; i++)
2941 tree arg = gimple_call_arg (stmt, i);
2942 if (arg == ddef)
2943 recognized_stmt_uses++;
2944 else if (load_from_dereferenced_name (arg, ddef))
2946 load_dereferenced = true;
2947 recognized_stmt_uses++;
2951 if (recognized_stmt_uses != all_stmt_uses)
2953 call_uses = IPA_UNDESCRIBED_USE;
2954 break;
2956 if (call_uses >= 0)
2957 call_uses += all_stmt_uses;
2959 else if (gimple_assign_single_p (stmt))
2961 tree rhs = gimple_assign_rhs1 (stmt);
2962 if (all_stmt_uses != 1
2963 || !load_from_dereferenced_name (rhs, ddef))
2965 call_uses = IPA_UNDESCRIBED_USE;
2966 break;
2968 load_dereferenced = true;
2970 else
2972 call_uses = IPA_UNDESCRIBED_USE;
2973 break;
2977 else
2978 call_uses = 0;
2980 else
2981 call_uses = IPA_UNDESCRIBED_USE;
2982 ipa_set_controlled_uses (info, i, call_uses);
2983 ipa_set_param_load_dereferenced (info, i, load_dereferenced);
2987 /* Free stuff in BI. */
2989 static void
2990 free_ipa_bb_info (struct ipa_bb_info *bi)
2992 bi->cg_edges.release ();
2993 bi->param_aa_statuses.release ();
2996 /* Dominator walker driving the analysis. */
2998 class analysis_dom_walker : public dom_walker
3000 public:
3001 analysis_dom_walker (struct ipa_func_body_info *fbi)
3002 : dom_walker (CDI_DOMINATORS), m_fbi (fbi) {}
3004 virtual edge before_dom_children (basic_block);
3006 private:
3007 struct ipa_func_body_info *m_fbi;
3010 edge
3011 analysis_dom_walker::before_dom_children (basic_block bb)
3013 ipa_analyze_params_uses_in_bb (m_fbi, bb);
3014 ipa_compute_jump_functions_for_bb (m_fbi, bb);
3015 return NULL;
3018 /* Release body info FBI. */
3020 void
3021 ipa_release_body_info (struct ipa_func_body_info *fbi)
3023 int i;
3024 struct ipa_bb_info *bi;
3026 FOR_EACH_VEC_ELT (fbi->bb_infos, i, bi)
3027 free_ipa_bb_info (bi);
3028 fbi->bb_infos.release ();
3031 /* Initialize the array describing properties of formal parameters
3032 of NODE, analyze their uses and compute jump functions associated
3033 with actual arguments of calls from within NODE. */
3035 void
3036 ipa_analyze_node (struct cgraph_node *node)
3038 struct ipa_func_body_info fbi;
3039 class ipa_node_params *info;
3041 ipa_check_create_node_params ();
3042 ipa_check_create_edge_args ();
3043 info = ipa_node_params_sum->get_create (node);
3045 if (info->analysis_done)
3046 return;
3047 info->analysis_done = 1;
3049 if (ipa_func_spec_opts_forbid_analysis_p (node))
3051 for (int i = 0; i < ipa_get_param_count (info); i++)
3053 ipa_set_param_used (info, i, true);
3054 ipa_set_controlled_uses (info, i, IPA_UNDESCRIBED_USE);
3056 return;
3059 struct function *func = DECL_STRUCT_FUNCTION (node->decl);
3060 push_cfun (func);
3061 calculate_dominance_info (CDI_DOMINATORS);
3062 ipa_initialize_node_params (node);
3063 ipa_analyze_controlled_uses (node);
3065 fbi.node = node;
3066 fbi.info = info;
3067 fbi.bb_infos = vNULL;
3068 fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
3069 fbi.param_count = ipa_get_param_count (info);
3070 fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps);
3072 for (struct cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
3074 ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
3075 bi->cg_edges.safe_push (cs);
3078 for (struct cgraph_edge *cs = node->indirect_calls; cs; cs = cs->next_callee)
3080 ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
3081 bi->cg_edges.safe_push (cs);
3084 analysis_dom_walker (&fbi).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
3086 ipa_release_body_info (&fbi);
3087 free_dominance_info (CDI_DOMINATORS);
3088 pop_cfun ();
3091 /* Update the jump functions associated with call graph edge E when the call
3092 graph edge CS is being inlined, assuming that E->caller is already (possibly
3093 indirectly) inlined into CS->callee and that E has not been inlined. */
3095 static void
3096 update_jump_functions_after_inlining (struct cgraph_edge *cs,
3097 struct cgraph_edge *e)
3099 ipa_edge_args *top = ipa_edge_args_sum->get (cs);
3100 ipa_edge_args *args = ipa_edge_args_sum->get (e);
3101 if (!args)
3102 return;
3103 int count = ipa_get_cs_argument_count (args);
3104 int i;
3106 for (i = 0; i < count; i++)
3108 struct ipa_jump_func *dst = ipa_get_ith_jump_func (args, i);
3109 class ipa_polymorphic_call_context *dst_ctx
3110 = ipa_get_ith_polymorhic_call_context (args, i);
3112 if (dst->agg.items)
3114 struct ipa_agg_jf_item *item;
3115 int j;
3117 FOR_EACH_VEC_ELT (*dst->agg.items, j, item)
3119 int dst_fid;
3120 struct ipa_jump_func *src;
3122 if (item->jftype != IPA_JF_PASS_THROUGH
3123 && item->jftype != IPA_JF_LOAD_AGG)
3124 continue;
3126 dst_fid = item->value.pass_through.formal_id;
3127 if (!top || dst_fid >= ipa_get_cs_argument_count (top))
3129 item->jftype = IPA_JF_UNKNOWN;
3130 continue;
3133 item->value.pass_through.formal_id = -1;
3134 src = ipa_get_ith_jump_func (top, dst_fid);
3135 if (src->type == IPA_JF_CONST)
3137 if (item->jftype == IPA_JF_PASS_THROUGH
3138 && item->value.pass_through.operation == NOP_EXPR)
3140 item->jftype = IPA_JF_CONST;
3141 item->value.constant = src->value.constant.value;
3142 continue;
3145 else if (src->type == IPA_JF_PASS_THROUGH
3146 && src->value.pass_through.operation == NOP_EXPR)
3148 if (item->jftype == IPA_JF_PASS_THROUGH
3149 || !item->value.load_agg.by_ref
3150 || src->value.pass_through.agg_preserved)
3151 item->value.pass_through.formal_id
3152 = src->value.pass_through.formal_id;
3154 else if (src->type == IPA_JF_ANCESTOR)
3156 if (item->jftype == IPA_JF_PASS_THROUGH)
3158 if (!src->value.ancestor.offset)
3159 item->value.pass_through.formal_id
3160 = src->value.ancestor.formal_id;
3162 else if (src->value.ancestor.agg_preserved)
3164 gcc_checking_assert (item->value.load_agg.by_ref);
3166 item->value.pass_through.formal_id
3167 = src->value.ancestor.formal_id;
3168 item->value.load_agg.offset
3169 += src->value.ancestor.offset;
3173 if (item->value.pass_through.formal_id < 0)
3174 item->jftype = IPA_JF_UNKNOWN;
3178 if (!top)
3180 ipa_set_jf_unknown (dst);
3181 continue;
3184 if (dst->type == IPA_JF_ANCESTOR)
3186 struct ipa_jump_func *src;
3187 int dst_fid = dst->value.ancestor.formal_id;
3188 class ipa_polymorphic_call_context *src_ctx
3189 = ipa_get_ith_polymorhic_call_context (top, dst_fid);
3191 /* Variable number of arguments can cause havoc if we try to access
3192 one that does not exist in the inlined edge. So make sure we
3193 don't. */
3194 if (dst_fid >= ipa_get_cs_argument_count (top))
3196 ipa_set_jf_unknown (dst);
3197 continue;
3200 src = ipa_get_ith_jump_func (top, dst_fid);
3202 if (src_ctx && !src_ctx->useless_p ())
3204 class ipa_polymorphic_call_context ctx = *src_ctx;
3206 /* TODO: Make type preserved safe WRT contexts. */
3207 if (!ipa_get_jf_ancestor_type_preserved (dst))
3208 ctx.possible_dynamic_type_change (e->in_polymorphic_cdtor);
3209 ctx.offset_by (dst->value.ancestor.offset);
3210 if (!ctx.useless_p ())
3212 if (!dst_ctx)
3214 vec_safe_grow_cleared (args->polymorphic_call_contexts,
3215 count, true);
3216 dst_ctx = ipa_get_ith_polymorhic_call_context (args, i);
3219 dst_ctx->combine_with (ctx);
3223 /* Parameter and argument in ancestor jump function must be pointer
3224 type, which means access to aggregate must be by-reference. */
3225 gcc_assert (!src->agg.items || src->agg.by_ref);
3227 if (src->agg.items && dst->value.ancestor.agg_preserved)
3229 struct ipa_agg_jf_item *item;
3230 int j;
3232 /* Currently we do not produce clobber aggregate jump functions,
3233 replace with merging when we do. */
3234 gcc_assert (!dst->agg.items);
3236 dst->agg.items = vec_safe_copy (src->agg.items);
3237 dst->agg.by_ref = src->agg.by_ref;
3238 FOR_EACH_VEC_SAFE_ELT (dst->agg.items, j, item)
3239 item->offset -= dst->value.ancestor.offset;
3242 if (src->type == IPA_JF_PASS_THROUGH
3243 && src->value.pass_through.operation == NOP_EXPR)
3245 dst->value.ancestor.formal_id = src->value.pass_through.formal_id;
3246 dst->value.ancestor.agg_preserved &=
3247 src->value.pass_through.agg_preserved;
3249 else if (src->type == IPA_JF_ANCESTOR)
3251 dst->value.ancestor.formal_id = src->value.ancestor.formal_id;
3252 dst->value.ancestor.offset += src->value.ancestor.offset;
3253 dst->value.ancestor.agg_preserved &=
3254 src->value.ancestor.agg_preserved;
3256 else
3257 ipa_set_jf_unknown (dst);
3259 else if (dst->type == IPA_JF_PASS_THROUGH)
3261 struct ipa_jump_func *src;
3262 /* We must check range due to calls with variable number of arguments
3263 and we cannot combine jump functions with operations. */
3264 if (dst->value.pass_through.operation == NOP_EXPR
3265 && (top && dst->value.pass_through.formal_id
3266 < ipa_get_cs_argument_count (top)))
3268 int dst_fid = dst->value.pass_through.formal_id;
3269 src = ipa_get_ith_jump_func (top, dst_fid);
3270 bool dst_agg_p = ipa_get_jf_pass_through_agg_preserved (dst);
3271 class ipa_polymorphic_call_context *src_ctx
3272 = ipa_get_ith_polymorhic_call_context (top, dst_fid);
3274 if (src_ctx && !src_ctx->useless_p ())
3276 class ipa_polymorphic_call_context ctx = *src_ctx;
3278 /* TODO: Make type preserved safe WRT contexts. */
3279 if (!ipa_get_jf_pass_through_type_preserved (dst))
3280 ctx.possible_dynamic_type_change (e->in_polymorphic_cdtor);
3281 if (!ctx.useless_p ())
3283 if (!dst_ctx)
3285 vec_safe_grow_cleared (args->polymorphic_call_contexts,
3286 count, true);
3287 dst_ctx = ipa_get_ith_polymorhic_call_context (args, i);
3289 dst_ctx->combine_with (ctx);
3292 switch (src->type)
3294 case IPA_JF_UNKNOWN:
3295 ipa_set_jf_unknown (dst);
3296 break;
3297 case IPA_JF_CONST:
3298 ipa_set_jf_cst_copy (dst, src);
3299 break;
3301 case IPA_JF_PASS_THROUGH:
3303 int formal_id = ipa_get_jf_pass_through_formal_id (src);
3304 enum tree_code operation;
3305 operation = ipa_get_jf_pass_through_operation (src);
3307 if (operation == NOP_EXPR)
3309 bool agg_p;
3310 agg_p = dst_agg_p
3311 && ipa_get_jf_pass_through_agg_preserved (src);
3312 ipa_set_jf_simple_pass_through (dst, formal_id, agg_p);
3314 else if (TREE_CODE_CLASS (operation) == tcc_unary)
3315 ipa_set_jf_unary_pass_through (dst, formal_id, operation);
3316 else
3318 tree operand = ipa_get_jf_pass_through_operand (src);
3319 ipa_set_jf_arith_pass_through (dst, formal_id, operand,
3320 operation);
3322 break;
3324 case IPA_JF_ANCESTOR:
3326 bool agg_p;
3327 agg_p = dst_agg_p
3328 && ipa_get_jf_ancestor_agg_preserved (src);
3329 ipa_set_ancestor_jf (dst,
3330 ipa_get_jf_ancestor_offset (src),
3331 ipa_get_jf_ancestor_formal_id (src),
3332 agg_p);
3333 break;
3335 default:
3336 gcc_unreachable ();
3339 if (src->agg.items
3340 && (dst_agg_p || !src->agg.by_ref))
3342 /* Currently we do not produce clobber aggregate jump
3343 functions, replace with merging when we do. */
3344 gcc_assert (!dst->agg.items);
3346 dst->agg.by_ref = src->agg.by_ref;
3347 dst->agg.items = vec_safe_copy (src->agg.items);
3350 else
3351 ipa_set_jf_unknown (dst);
3356 /* If TARGET is an addr_expr of a function declaration, make it the
3357 (SPECULATIVE)destination of an indirect edge IE and return the edge.
3358 Otherwise, return NULL. */
3360 struct cgraph_edge *
3361 ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
3362 bool speculative)
3364 struct cgraph_node *callee;
3365 bool unreachable = false;
3367 if (TREE_CODE (target) == ADDR_EXPR)
3368 target = TREE_OPERAND (target, 0);
3369 if (TREE_CODE (target) != FUNCTION_DECL)
3371 target = canonicalize_constructor_val (target, NULL);
3372 if (!target || TREE_CODE (target) != FUNCTION_DECL)
3374 /* Member pointer call that goes through a VMT lookup. */
3375 if (ie->indirect_info->member_ptr
3376 /* Or if target is not an invariant expression and we do not
3377 know if it will evaulate to function at runtime.
3378 This can happen when folding through &VAR, where &VAR
3379 is IP invariant, but VAR itself is not.
3381 TODO: Revisit this when GCC 5 is branched. It seems that
3382 member_ptr check is not needed and that we may try to fold
3383 the expression and see if VAR is readonly. */
3384 || !is_gimple_ip_invariant (target))
3386 if (dump_enabled_p ())
3388 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
3389 "discovered direct call non-invariant %s\n",
3390 ie->caller->dump_name ());
3392 return NULL;
3396 if (dump_enabled_p ())
3398 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
3399 "discovered direct call to non-function in %s, "
3400 "making it __builtin_unreachable\n",
3401 ie->caller->dump_name ());
3404 target = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
3405 callee = cgraph_node::get_create (target);
3406 unreachable = true;
3408 else
3409 callee = cgraph_node::get (target);
3411 else
3412 callee = cgraph_node::get (target);
3414 /* Because may-edges are not explicitely represented and vtable may be external,
3415 we may create the first reference to the object in the unit. */
3416 if (!callee || callee->inlined_to)
3419 /* We are better to ensure we can refer to it.
3420 In the case of static functions we are out of luck, since we already
3421 removed its body. In the case of public functions we may or may
3422 not introduce the reference. */
3423 if (!canonicalize_constructor_val (target, NULL)
3424 || !TREE_PUBLIC (target))
3426 if (dump_file)
3427 fprintf (dump_file, "ipa-prop: Discovered call to a known target "
3428 "(%s -> %s) but cannot refer to it. Giving up.\n",
3429 ie->caller->dump_name (),
3430 ie->callee->dump_name ());
3431 return NULL;
3433 callee = cgraph_node::get_create (target);
3436 /* If the edge is already speculated. */
3437 if (speculative && ie->speculative)
3439 if (dump_file)
3441 cgraph_edge *e2 = ie->speculative_call_for_target (callee);
3442 if (!e2)
3444 if (dump_file)
3445 fprintf (dump_file, "ipa-prop: Discovered call to a "
3446 "speculative target (%s -> %s) but the call is "
3447 "already speculated to different target. "
3448 "Giving up.\n",
3449 ie->caller->dump_name (), callee->dump_name ());
3451 else
3453 if (dump_file)
3454 fprintf (dump_file,
3455 "ipa-prop: Discovered call to a speculative target "
3456 "(%s -> %s) this agree with previous speculation.\n",
3457 ie->caller->dump_name (), callee->dump_name ());
3460 return NULL;
3463 if (!dbg_cnt (devirt))
3464 return NULL;
3466 ipa_check_create_node_params ();
3468 /* We cannot make edges to inline clones. It is bug that someone removed
3469 the cgraph node too early. */
3470 gcc_assert (!callee->inlined_to);
3472 if (dump_file && !unreachable)
3474 fprintf (dump_file, "ipa-prop: Discovered %s call to a %s target "
3475 "(%s -> %s), for stmt ",
3476 ie->indirect_info->polymorphic ? "a virtual" : "an indirect",
3477 speculative ? "speculative" : "known",
3478 ie->caller->dump_name (),
3479 callee->dump_name ());
3480 if (ie->call_stmt)
3481 print_gimple_stmt (dump_file, ie->call_stmt, 2, TDF_SLIM);
3482 else
3483 fprintf (dump_file, "with uid %i\n", ie->lto_stmt_uid);
3485 if (dump_enabled_p ())
3487 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
3488 "converting indirect call in %s to direct call to %s\n",
3489 ie->caller->dump_name (), callee->dump_name ());
3491 if (!speculative)
3493 struct cgraph_edge *orig = ie;
3494 ie = cgraph_edge::make_direct (ie, callee);
3495 /* If we resolved speculative edge the cost is already up to date
3496 for direct call (adjusted by inline_edge_duplication_hook). */
3497 if (ie == orig)
3499 ipa_call_summary *es = ipa_call_summaries->get (ie);
3500 es->call_stmt_size -= (eni_size_weights.indirect_call_cost
3501 - eni_size_weights.call_cost);
3502 es->call_stmt_time -= (eni_time_weights.indirect_call_cost
3503 - eni_time_weights.call_cost);
3506 else
3508 if (!callee->can_be_discarded_p ())
3510 cgraph_node *alias;
3511 alias = dyn_cast<cgraph_node *> (callee->noninterposable_alias ());
3512 if (alias)
3513 callee = alias;
3515 /* make_speculative will update ie's cost to direct call cost. */
3516 ie = ie->make_speculative
3517 (callee, ie->count.apply_scale (8, 10));
3520 return ie;
3523 /* Attempt to locate an interprocedural constant at a given REQ_OFFSET in
3524 CONSTRUCTOR and return it. Return NULL if the search fails for some
3525 reason. */
3527 static tree
3528 find_constructor_constant_at_offset (tree constructor, HOST_WIDE_INT req_offset)
3530 tree type = TREE_TYPE (constructor);
3531 if (TREE_CODE (type) != ARRAY_TYPE
3532 && TREE_CODE (type) != RECORD_TYPE)
3533 return NULL;
3535 unsigned ix;
3536 tree index, val;
3537 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (constructor), ix, index, val)
3539 HOST_WIDE_INT elt_offset;
3540 if (TREE_CODE (type) == ARRAY_TYPE)
3542 offset_int off;
3543 tree unit_size = TYPE_SIZE_UNIT (TREE_TYPE (type));
3544 gcc_assert (TREE_CODE (unit_size) == INTEGER_CST);
3546 if (index)
3548 if (TREE_CODE (index) == RANGE_EXPR)
3549 off = wi::to_offset (TREE_OPERAND (index, 0));
3550 else
3551 off = wi::to_offset (index);
3552 if (TYPE_DOMAIN (type) && TYPE_MIN_VALUE (TYPE_DOMAIN (type)))
3554 tree low_bound = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
3555 gcc_assert (TREE_CODE (unit_size) == INTEGER_CST);
3556 off = wi::sext (off - wi::to_offset (low_bound),
3557 TYPE_PRECISION (TREE_TYPE (index)));
3559 off *= wi::to_offset (unit_size);
3560 /* ??? Handle more than just the first index of a
3561 RANGE_EXPR. */
3563 else
3564 off = wi::to_offset (unit_size) * ix;
3566 off = wi::lshift (off, LOG2_BITS_PER_UNIT);
3567 if (!wi::fits_shwi_p (off) || wi::neg_p (off))
3568 continue;
3569 elt_offset = off.to_shwi ();
3571 else if (TREE_CODE (type) == RECORD_TYPE)
3573 gcc_checking_assert (index && TREE_CODE (index) == FIELD_DECL);
3574 if (DECL_BIT_FIELD (index))
3575 continue;
3576 elt_offset = int_bit_position (index);
3578 else
3579 gcc_unreachable ();
3581 if (elt_offset > req_offset)
3582 return NULL;
3584 if (TREE_CODE (val) == CONSTRUCTOR)
3585 return find_constructor_constant_at_offset (val,
3586 req_offset - elt_offset);
3588 if (elt_offset == req_offset
3589 && is_gimple_reg_type (TREE_TYPE (val))
3590 && is_gimple_ip_invariant (val))
3591 return val;
3593 return NULL;
3596 /* Check whether SCALAR could be used to look up an aggregate interprocedural
3597 invariant from a static constructor and if so, return it. Otherwise return
3598 NULL. */
3600 static tree
3601 ipa_find_agg_cst_from_init (tree scalar, HOST_WIDE_INT offset, bool by_ref)
3603 if (by_ref)
3605 if (TREE_CODE (scalar) != ADDR_EXPR)
3606 return NULL;
3607 scalar = TREE_OPERAND (scalar, 0);
3610 if (!VAR_P (scalar)
3611 || !is_global_var (scalar)
3612 || !TREE_READONLY (scalar)
3613 || !DECL_INITIAL (scalar)
3614 || TREE_CODE (DECL_INITIAL (scalar)) != CONSTRUCTOR)
3615 return NULL;
3617 return find_constructor_constant_at_offset (DECL_INITIAL (scalar), offset);
3620 /* Retrieve value from AGG, a set of known offset/value for an aggregate or
3621 static initializer of SCALAR (which can be NULL) for the given OFFSET or
3622 return NULL if there is none. BY_REF specifies whether the value has to be
3623 passed by reference or by value. If FROM_GLOBAL_CONSTANT is non-NULL, then
3624 the boolean it points to is set to true if the value comes from an
3625 initializer of a constant. */
3627 tree
3628 ipa_find_agg_cst_for_param (const ipa_agg_value_set *agg, tree scalar,
3629 HOST_WIDE_INT offset, bool by_ref,
3630 bool *from_global_constant)
3632 struct ipa_agg_value *item;
3633 int i;
3635 if (scalar)
3637 tree res = ipa_find_agg_cst_from_init (scalar, offset, by_ref);
3638 if (res)
3640 if (from_global_constant)
3641 *from_global_constant = true;
3642 return res;
3646 if (!agg
3647 || by_ref != agg->by_ref)
3648 return NULL;
3650 FOR_EACH_VEC_ELT (agg->items, i, item)
3651 if (item->offset == offset)
3653 /* Currently we do not have clobber values, return NULL for them once
3654 we do. */
3655 gcc_checking_assert (is_gimple_ip_invariant (item->value));
3656 if (from_global_constant)
3657 *from_global_constant = false;
3658 return item->value;
3660 return NULL;
3663 /* Remove a reference to SYMBOL from the list of references of a node given by
3664 reference description RDESC. Return true if the reference has been
3665 successfully found and removed. */
3667 static bool
3668 remove_described_reference (symtab_node *symbol, struct ipa_cst_ref_desc *rdesc)
3670 struct ipa_ref *to_del;
3671 struct cgraph_edge *origin;
3673 origin = rdesc->cs;
3674 if (!origin)
3675 return false;
3676 to_del = origin->caller->find_reference (symbol, origin->call_stmt,
3677 origin->lto_stmt_uid);
3678 if (!to_del)
3679 return false;
3681 to_del->remove_reference ();
3682 if (dump_file)
3683 fprintf (dump_file, "ipa-prop: Removed a reference from %s to %s.\n",
3684 origin->caller->dump_name (), symbol->dump_name ());
3685 return true;
3688 /* If JFUNC has a reference description with refcount different from
3689 IPA_UNDESCRIBED_USE, return the reference description, otherwise return
3690 NULL. JFUNC must be a constant jump function. */
3692 static struct ipa_cst_ref_desc *
3693 jfunc_rdesc_usable (struct ipa_jump_func *jfunc)
3695 struct ipa_cst_ref_desc *rdesc = ipa_get_jf_constant_rdesc (jfunc);
3696 if (rdesc && rdesc->refcount != IPA_UNDESCRIBED_USE)
3697 return rdesc;
3698 else
3699 return NULL;
3702 /* If the value of constant jump function JFUNC is an address of a function
3703 declaration, return the associated call graph node. Otherwise return
3704 NULL. */
3706 static symtab_node *
3707 symtab_node_for_jfunc (struct ipa_jump_func *jfunc)
3709 gcc_checking_assert (jfunc->type == IPA_JF_CONST);
3710 tree cst = ipa_get_jf_constant (jfunc);
3711 if (TREE_CODE (cst) != ADDR_EXPR
3712 || (TREE_CODE (TREE_OPERAND (cst, 0)) != FUNCTION_DECL
3713 && TREE_CODE (TREE_OPERAND (cst, 0)) != VAR_DECL))
3714 return NULL;
3716 return symtab_node::get (TREE_OPERAND (cst, 0));
3720 /* If JFUNC is a constant jump function with a usable rdesc, decrement its
3721 refcount and if it hits zero, remove reference to SYMBOL from the caller of
3722 the edge specified in the rdesc. Return false if either the symbol or the
3723 reference could not be found, otherwise return true. */
3725 static bool
3726 try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc)
3728 struct ipa_cst_ref_desc *rdesc;
3729 if (jfunc->type == IPA_JF_CONST
3730 && (rdesc = jfunc_rdesc_usable (jfunc))
3731 && --rdesc->refcount == 0)
3733 symtab_node *symbol = symtab_node_for_jfunc (jfunc);
3734 if (!symbol)
3735 return false;
3737 return remove_described_reference (symbol, rdesc);
3739 return true;
3742 /* Try to find a destination for indirect edge IE that corresponds to a simple
3743 call or a call of a member function pointer and where the destination is a
3744 pointer formal parameter described by jump function JFUNC. TARGET_TYPE is
3745 the type of the parameter to which the result of JFUNC is passed. If it can
3746 be determined, return the newly direct edge, otherwise return NULL.
3747 NEW_ROOT and NEW_ROOT_INFO is the node and its info that JFUNC lattices are
3748 relative to. */
3750 static struct cgraph_edge *
3751 try_make_edge_direct_simple_call (struct cgraph_edge *ie,
3752 struct ipa_jump_func *jfunc, tree target_type,
3753 struct cgraph_node *new_root,
3754 class ipa_node_params *new_root_info)
3756 struct cgraph_edge *cs;
3757 tree target;
3758 bool agg_contents = ie->indirect_info->agg_contents;
3759 tree scalar = ipa_value_from_jfunc (new_root_info, jfunc, target_type);
3760 if (agg_contents)
3762 bool from_global_constant;
3763 ipa_agg_value_set agg = ipa_agg_value_set_from_jfunc (new_root_info,
3764 new_root,
3765 &jfunc->agg);
3766 target = ipa_find_agg_cst_for_param (&agg, scalar,
3767 ie->indirect_info->offset,
3768 ie->indirect_info->by_ref,
3769 &from_global_constant);
3770 agg.release ();
3771 if (target
3772 && !from_global_constant
3773 && !ie->indirect_info->guaranteed_unmodified)
3774 return NULL;
3776 else
3777 target = scalar;
3778 if (!target)
3779 return NULL;
3780 cs = ipa_make_edge_direct_to_target (ie, target);
3782 if (cs && !agg_contents)
3784 bool ok;
3785 gcc_checking_assert (cs->callee
3786 && (cs != ie
3787 || jfunc->type != IPA_JF_CONST
3788 || !symtab_node_for_jfunc (jfunc)
3789 || cs->callee == symtab_node_for_jfunc (jfunc)));
3790 ok = try_decrement_rdesc_refcount (jfunc);
3791 gcc_checking_assert (ok);
3794 return cs;
3797 /* Return the target to be used in cases of impossible devirtualization. IE
3798 and target (the latter can be NULL) are dumped when dumping is enabled. */
3800 tree
3801 ipa_impossible_devirt_target (struct cgraph_edge *ie, tree target)
3803 if (dump_file)
3805 if (target)
3806 fprintf (dump_file,
3807 "Type inconsistent devirtualization: %s->%s\n",
3808 ie->caller->dump_name (),
3809 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (target)));
3810 else
3811 fprintf (dump_file,
3812 "No devirtualization target in %s\n",
3813 ie->caller->dump_name ());
3815 tree new_target = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
3816 cgraph_node::get_create (new_target);
3817 return new_target;
3820 /* Try to find a destination for indirect edge IE that corresponds to a virtual
3821 call based on a formal parameter which is described by jump function JFUNC
3822 and if it can be determined, make it direct and return the direct edge.
3823 Otherwise, return NULL. CTX describes the polymorphic context that the
3824 parameter the call is based on brings along with it. NEW_ROOT and
3825 NEW_ROOT_INFO is the node and its info that JFUNC lattices are relative
3826 to. */
3828 static struct cgraph_edge *
3829 try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
3830 struct ipa_jump_func *jfunc,
3831 class ipa_polymorphic_call_context ctx,
3832 struct cgraph_node *new_root,
3833 class ipa_node_params *new_root_info)
3835 tree target = NULL;
3836 bool speculative = false;
3838 if (!opt_for_fn (ie->caller->decl, flag_devirtualize))
3839 return NULL;
3841 gcc_assert (!ie->indirect_info->by_ref);
3843 /* Try to do lookup via known virtual table pointer value. */
3844 if (!ie->indirect_info->vptr_changed
3845 || opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively))
3847 tree vtable;
3848 unsigned HOST_WIDE_INT offset;
3849 tree scalar = (jfunc->type == IPA_JF_CONST) ? ipa_get_jf_constant (jfunc)
3850 : NULL;
3851 ipa_agg_value_set agg = ipa_agg_value_set_from_jfunc (new_root_info,
3852 new_root,
3853 &jfunc->agg);
3854 tree t = ipa_find_agg_cst_for_param (&agg, scalar,
3855 ie->indirect_info->offset,
3856 true);
3857 agg.release ();
3858 if (t && vtable_pointer_value_to_vtable (t, &vtable, &offset))
3860 bool can_refer;
3861 t = gimple_get_virt_method_for_vtable (ie->indirect_info->otr_token,
3862 vtable, offset, &can_refer);
3863 if (can_refer)
3865 if (!t
3866 || fndecl_built_in_p (t, BUILT_IN_UNREACHABLE)
3867 || !possible_polymorphic_call_target_p
3868 (ie, cgraph_node::get (t)))
3870 /* Do not speculate builtin_unreachable, it is stupid! */
3871 if (!ie->indirect_info->vptr_changed)
3872 target = ipa_impossible_devirt_target (ie, target);
3873 else
3874 target = NULL;
3876 else
3878 target = t;
3879 speculative = ie->indirect_info->vptr_changed;
3885 ipa_polymorphic_call_context ie_context (ie);
3886 vec <cgraph_node *>targets;
3887 bool final;
3889 ctx.offset_by (ie->indirect_info->offset);
3890 if (ie->indirect_info->vptr_changed)
3891 ctx.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
3892 ie->indirect_info->otr_type);
3893 ctx.combine_with (ie_context, ie->indirect_info->otr_type);
3894 targets = possible_polymorphic_call_targets
3895 (ie->indirect_info->otr_type,
3896 ie->indirect_info->otr_token,
3897 ctx, &final);
3898 if (final && targets.length () <= 1)
3900 speculative = false;
3901 if (targets.length () == 1)
3902 target = targets[0]->decl;
3903 else
3904 target = ipa_impossible_devirt_target (ie, NULL_TREE);
3906 else if (!target && opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively)
3907 && !ie->speculative && ie->maybe_hot_p ())
3909 cgraph_node *n;
3910 n = try_speculative_devirtualization (ie->indirect_info->otr_type,
3911 ie->indirect_info->otr_token,
3912 ie->indirect_info->context);
3913 if (n)
3915 target = n->decl;
3916 speculative = true;
3920 if (target)
3922 if (!possible_polymorphic_call_target_p
3923 (ie, cgraph_node::get_create (target)))
3925 if (speculative)
3926 return NULL;
3927 target = ipa_impossible_devirt_target (ie, target);
3929 return ipa_make_edge_direct_to_target (ie, target, speculative);
3931 else
3932 return NULL;
3935 /* Update the param called notes associated with NODE when CS is being inlined,
3936 assuming NODE is (potentially indirectly) inlined into CS->callee.
3937 Moreover, if the callee is discovered to be constant, create a new cgraph
3938 edge for it. Newly discovered indirect edges will be added to *NEW_EDGES,
3939 unless NEW_EDGES is NULL. Return true iff a new edge(s) were created. */
3941 static bool
3942 update_indirect_edges_after_inlining (struct cgraph_edge *cs,
3943 struct cgraph_node *node,
3944 vec<cgraph_edge *> *new_edges)
3946 class ipa_edge_args *top;
3947 struct cgraph_edge *ie, *next_ie, *new_direct_edge;
3948 struct cgraph_node *new_root;
3949 class ipa_node_params *new_root_info, *inlined_node_info;
3950 bool res = false;
3952 ipa_check_create_edge_args ();
3953 top = ipa_edge_args_sum->get (cs);
3954 new_root = cs->caller->inlined_to
3955 ? cs->caller->inlined_to : cs->caller;
3956 new_root_info = ipa_node_params_sum->get (new_root);
3957 inlined_node_info = ipa_node_params_sum->get (cs->callee->function_symbol ());
3959 for (ie = node->indirect_calls; ie; ie = next_ie)
3961 class cgraph_indirect_call_info *ici = ie->indirect_info;
3962 struct ipa_jump_func *jfunc;
3963 int param_index;
3965 next_ie = ie->next_callee;
3967 if (ici->param_index == -1)
3968 continue;
3970 /* We must check range due to calls with variable number of arguments: */
3971 if (!top || ici->param_index >= ipa_get_cs_argument_count (top))
3973 ici->param_index = -1;
3974 continue;
3977 param_index = ici->param_index;
3978 jfunc = ipa_get_ith_jump_func (top, param_index);
3980 auto_vec<cgraph_node *, 4> spec_targets;
3981 if (ie->speculative)
3982 for (cgraph_edge *direct = ie->first_speculative_call_target ();
3983 direct;
3984 direct = direct->next_speculative_call_target ())
3985 spec_targets.safe_push (direct->callee);
3987 if (!opt_for_fn (node->decl, flag_indirect_inlining))
3988 new_direct_edge = NULL;
3989 else if (ici->polymorphic)
3991 ipa_polymorphic_call_context ctx;
3992 ctx = ipa_context_from_jfunc (new_root_info, cs, param_index, jfunc);
3993 new_direct_edge = try_make_edge_direct_virtual_call (ie, jfunc, ctx,
3994 new_root,
3995 new_root_info);
3997 else
3999 tree target_type = ipa_get_type (inlined_node_info, param_index);
4000 new_direct_edge = try_make_edge_direct_simple_call (ie, jfunc,
4001 target_type,
4002 new_root,
4003 new_root_info);
4006 /* If speculation was removed, then we need to do nothing. */
4007 if (new_direct_edge && new_direct_edge != ie
4008 && spec_targets.contains (new_direct_edge->callee))
4010 new_direct_edge->indirect_inlining_edge = 1;
4011 res = true;
4012 if (!new_direct_edge->speculative)
4013 continue;
4015 else if (new_direct_edge)
4017 new_direct_edge->indirect_inlining_edge = 1;
4018 if (new_edges)
4020 new_edges->safe_push (new_direct_edge);
4021 res = true;
4023 /* If speculative edge was introduced we still need to update
4024 call info of the indirect edge. */
4025 if (!new_direct_edge->speculative)
4026 continue;
4028 if (jfunc->type == IPA_JF_PASS_THROUGH
4029 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
4031 if (ici->agg_contents
4032 && !ipa_get_jf_pass_through_agg_preserved (jfunc)
4033 && !ici->polymorphic)
4034 ici->param_index = -1;
4035 else
4037 ici->param_index = ipa_get_jf_pass_through_formal_id (jfunc);
4038 if (ici->polymorphic
4039 && !ipa_get_jf_pass_through_type_preserved (jfunc))
4040 ici->vptr_changed = true;
4041 ipa_set_param_used_by_indirect_call (new_root_info,
4042 ici->param_index, true);
4043 if (ici->polymorphic)
4044 ipa_set_param_used_by_polymorphic_call (new_root_info,
4045 ici->param_index, true);
4048 else if (jfunc->type == IPA_JF_ANCESTOR)
4050 if (ici->agg_contents
4051 && !ipa_get_jf_ancestor_agg_preserved (jfunc)
4052 && !ici->polymorphic)
4053 ici->param_index = -1;
4054 else
4056 ici->param_index = ipa_get_jf_ancestor_formal_id (jfunc);
4057 ici->offset += ipa_get_jf_ancestor_offset (jfunc);
4058 if (ici->polymorphic
4059 && !ipa_get_jf_ancestor_type_preserved (jfunc))
4060 ici->vptr_changed = true;
4061 ipa_set_param_used_by_indirect_call (new_root_info,
4062 ici->param_index, true);
4063 if (ici->polymorphic)
4064 ipa_set_param_used_by_polymorphic_call (new_root_info,
4065 ici->param_index, true);
4068 else
4069 /* Either we can find a destination for this edge now or never. */
4070 ici->param_index = -1;
4073 return res;
4076 /* Recursively traverse subtree of NODE (including node) made of inlined
4077 cgraph_edges when CS has been inlined and invoke
4078 update_indirect_edges_after_inlining on all nodes and
4079 update_jump_functions_after_inlining on all non-inlined edges that lead out
4080 of this subtree. Newly discovered indirect edges will be added to
4081 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were
4082 created. */
4084 static bool
4085 propagate_info_to_inlined_callees (struct cgraph_edge *cs,
4086 struct cgraph_node *node,
4087 vec<cgraph_edge *> *new_edges)
4089 struct cgraph_edge *e;
4090 bool res;
4092 res = update_indirect_edges_after_inlining (cs, node, new_edges);
4094 for (e = node->callees; e; e = e->next_callee)
4095 if (!e->inline_failed)
4096 res |= propagate_info_to_inlined_callees (cs, e->callee, new_edges);
4097 else
4098 update_jump_functions_after_inlining (cs, e);
4099 for (e = node->indirect_calls; e; e = e->next_callee)
4100 update_jump_functions_after_inlining (cs, e);
4102 return res;
4105 /* Combine two controlled uses counts as done during inlining. */
4107 static int
4108 combine_controlled_uses_counters (int c, int d)
4110 if (c == IPA_UNDESCRIBED_USE || d == IPA_UNDESCRIBED_USE)
4111 return IPA_UNDESCRIBED_USE;
4112 else
4113 return c + d - 1;
4116 /* Propagate number of controlled users from CS->caleee to the new root of the
4117 tree of inlined nodes. */
4119 static void
4120 propagate_controlled_uses (struct cgraph_edge *cs)
4122 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
4123 if (!args)
4124 return;
4125 struct cgraph_node *new_root = cs->caller->inlined_to
4126 ? cs->caller->inlined_to : cs->caller;
4127 ipa_node_params *new_root_info = ipa_node_params_sum->get (new_root);
4128 ipa_node_params *old_root_info = ipa_node_params_sum->get (cs->callee);
4129 int count, i;
4131 if (!old_root_info)
4132 return;
4134 count = MIN (ipa_get_cs_argument_count (args),
4135 ipa_get_param_count (old_root_info));
4136 for (i = 0; i < count; i++)
4138 struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
4139 struct ipa_cst_ref_desc *rdesc;
4141 if (jf->type == IPA_JF_PASS_THROUGH)
4143 int src_idx, c, d;
4144 src_idx = ipa_get_jf_pass_through_formal_id (jf);
4145 c = ipa_get_controlled_uses (new_root_info, src_idx);
4146 d = ipa_get_controlled_uses (old_root_info, i);
4148 gcc_checking_assert (ipa_get_jf_pass_through_operation (jf)
4149 == NOP_EXPR || c == IPA_UNDESCRIBED_USE);
4150 c = combine_controlled_uses_counters (c, d);
4151 ipa_set_controlled_uses (new_root_info, src_idx, c);
4152 bool lderef = true;
4153 if (c != IPA_UNDESCRIBED_USE)
4155 lderef = (ipa_get_param_load_dereferenced (new_root_info, src_idx)
4156 || ipa_get_param_load_dereferenced (old_root_info, i));
4157 ipa_set_param_load_dereferenced (new_root_info, src_idx, lderef);
4160 if (c == 0 && !lderef && new_root_info->ipcp_orig_node)
4162 struct cgraph_node *n;
4163 struct ipa_ref *ref;
4164 tree t = new_root_info->known_csts[src_idx];
4166 if (t && TREE_CODE (t) == ADDR_EXPR
4167 && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
4168 && (n = cgraph_node::get (TREE_OPERAND (t, 0)))
4169 && (ref = new_root->find_reference (n, NULL, 0)))
4171 if (dump_file)
4172 fprintf (dump_file, "ipa-prop: Removing cloning-created "
4173 "reference from %s to %s.\n",
4174 new_root->dump_name (),
4175 n->dump_name ());
4176 ref->remove_reference ();
4180 else if (jf->type == IPA_JF_CONST
4181 && (rdesc = jfunc_rdesc_usable (jf)))
4183 int d = ipa_get_controlled_uses (old_root_info, i);
4184 int c = rdesc->refcount;
4185 rdesc->refcount = combine_controlled_uses_counters (c, d);
4186 if (rdesc->refcount == 0)
4188 tree cst = ipa_get_jf_constant (jf);
4189 gcc_checking_assert (TREE_CODE (cst) == ADDR_EXPR
4190 && ((TREE_CODE (TREE_OPERAND (cst, 0))
4191 == FUNCTION_DECL)
4192 || (TREE_CODE (TREE_OPERAND (cst, 0))
4193 == VAR_DECL)));
4195 symtab_node *n = symtab_node::get (TREE_OPERAND (cst, 0));
4196 if (n)
4198 struct cgraph_node *clone;
4199 bool removed = remove_described_reference (n, rdesc);
4200 /* The reference might have been removed by IPA-CP. */
4201 if (removed
4202 && ipa_get_param_load_dereferenced (old_root_info, i))
4204 new_root->create_reference (n, IPA_REF_LOAD, NULL);
4205 if (dump_file)
4206 fprintf (dump_file, "ipa-prop: ...replaced it with "
4207 "LOAD one from %s to %s.\n",
4208 new_root->dump_name (), n->dump_name ());
4211 clone = cs->caller;
4212 while (clone->inlined_to
4213 && clone->ipcp_clone
4214 && clone != rdesc->cs->caller)
4216 struct ipa_ref *ref;
4217 ref = clone->find_reference (n, NULL, 0);
4218 if (ref)
4220 if (dump_file)
4221 fprintf (dump_file, "ipa-prop: Removing "
4222 "cloning-created reference "
4223 "from %s to %s.\n",
4224 clone->dump_name (),
4225 n->dump_name ());
4226 ref->remove_reference ();
4228 clone = clone->callers->caller;
4235 for (i = ipa_get_param_count (old_root_info);
4236 i < ipa_get_cs_argument_count (args);
4237 i++)
4239 struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
4241 if (jf->type == IPA_JF_CONST)
4243 struct ipa_cst_ref_desc *rdesc = jfunc_rdesc_usable (jf);
4244 if (rdesc)
4245 rdesc->refcount = IPA_UNDESCRIBED_USE;
4247 else if (jf->type == IPA_JF_PASS_THROUGH)
4248 ipa_set_controlled_uses (new_root_info,
4249 jf->value.pass_through.formal_id,
4250 IPA_UNDESCRIBED_USE);
4254 /* Update jump functions and call note functions on inlining the call site CS.
4255 CS is expected to lead to a node already cloned by
4256 cgraph_clone_inline_nodes. Newly discovered indirect edges will be added to
4257 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were +
4258 created. */
4260 bool
4261 ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
4262 vec<cgraph_edge *> *new_edges)
4264 bool changed;
4265 /* Do nothing if the preparation phase has not been carried out yet
4266 (i.e. during early inlining). */
4267 if (!ipa_node_params_sum)
4268 return false;
4269 gcc_assert (ipa_edge_args_sum);
4271 propagate_controlled_uses (cs);
4272 changed = propagate_info_to_inlined_callees (cs, cs->callee, new_edges);
4273 ipa_node_params_sum->remove (cs->callee);
4275 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
4276 if (args)
4278 bool ok = true;
4279 if (args->jump_functions)
4281 struct ipa_jump_func *jf;
4282 int i;
4283 FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
4284 if (jf->type == IPA_JF_CONST
4285 && ipa_get_jf_constant_rdesc (jf))
4287 ok = false;
4288 break;
4291 if (ok)
4292 ipa_edge_args_sum->remove (cs);
4294 if (ipcp_transformation_sum)
4295 ipcp_transformation_sum->remove (cs->callee);
4297 return changed;
4300 /* Ensure that array of edge arguments infos is big enough to accommodate a
4301 structure for all edges and reallocates it if not. Also, allocate
4302 associated hash tables is they do not already exist. */
4304 void
4305 ipa_check_create_edge_args (void)
4307 if (!ipa_edge_args_sum)
4308 ipa_edge_args_sum
4309 = (new (ggc_alloc_no_dtor<ipa_edge_args_sum_t> ())
4310 ipa_edge_args_sum_t (symtab, true));
4311 if (!ipa_bits_hash_table)
4312 ipa_bits_hash_table = hash_table<ipa_bit_ggc_hash_traits>::create_ggc (37);
4313 if (!ipa_vr_hash_table)
4314 ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
4317 /* Free all ipa_edge structures. */
4319 void
4320 ipa_free_all_edge_args (void)
4322 if (!ipa_edge_args_sum)
4323 return;
4325 ggc_delete (ipa_edge_args_sum);
4326 ipa_edge_args_sum = NULL;
4329 /* Free all ipa_node_params structures. */
4331 void
4332 ipa_free_all_node_params (void)
4334 if (ipa_node_params_sum)
4335 ggc_delete (ipa_node_params_sum);
4336 ipa_node_params_sum = NULL;
4339 /* Initialize IPA CP transformation summary and also allocate any necessary hash
4340 tables if they do not already exist. */
4342 void
4343 ipcp_transformation_initialize (void)
4345 if (!ipa_bits_hash_table)
4346 ipa_bits_hash_table = hash_table<ipa_bit_ggc_hash_traits>::create_ggc (37);
4347 if (!ipa_vr_hash_table)
4348 ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
4349 if (ipcp_transformation_sum == NULL)
4351 ipcp_transformation_sum = ipcp_transformation_t::create_ggc (symtab);
4352 ipcp_transformation_sum->disable_insertion_hook ();
4356 /* Release the IPA CP transformation summary. */
4358 void
4359 ipcp_free_transformation_sum (void)
4361 if (!ipcp_transformation_sum)
4362 return;
4364 ipcp_transformation_sum->~function_summary<ipcp_transformation *> ();
4365 ggc_free (ipcp_transformation_sum);
4366 ipcp_transformation_sum = NULL;
4369 /* Set the aggregate replacements of NODE to be AGGVALS. */
4371 void
4372 ipa_set_node_agg_value_chain (struct cgraph_node *node,
4373 struct ipa_agg_replacement_value *aggvals)
4375 ipcp_transformation_initialize ();
4376 ipcp_transformation *s = ipcp_transformation_sum->get_create (node);
4377 s->agg_values = aggvals;
4380 /* Hook that is called by cgraph.c when an edge is removed. Adjust reference
4381 count data structures accordingly. */
4383 void
4384 ipa_edge_args_sum_t::remove (cgraph_edge *cs, ipa_edge_args *args)
4386 if (args->jump_functions)
4388 struct ipa_jump_func *jf;
4389 int i;
4390 FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
4392 struct ipa_cst_ref_desc *rdesc;
4393 try_decrement_rdesc_refcount (jf);
4394 if (jf->type == IPA_JF_CONST
4395 && (rdesc = ipa_get_jf_constant_rdesc (jf))
4396 && rdesc->cs == cs)
4397 rdesc->cs = NULL;
4402 /* Method invoked when an edge is duplicated. Copy ipa_edge_args and adjust
4403 reference count data strucutres accordingly. */
4405 void
4406 ipa_edge_args_sum_t::duplicate (cgraph_edge *src, cgraph_edge *dst,
4407 ipa_edge_args *old_args, ipa_edge_args *new_args)
4409 unsigned int i;
4411 new_args->jump_functions = vec_safe_copy (old_args->jump_functions);
4412 if (old_args->polymorphic_call_contexts)
4413 new_args->polymorphic_call_contexts
4414 = vec_safe_copy (old_args->polymorphic_call_contexts);
4416 for (i = 0; i < vec_safe_length (old_args->jump_functions); i++)
4418 struct ipa_jump_func *src_jf = ipa_get_ith_jump_func (old_args, i);
4419 struct ipa_jump_func *dst_jf = ipa_get_ith_jump_func (new_args, i);
4421 dst_jf->agg.items = vec_safe_copy (dst_jf->agg.items);
4423 if (src_jf->type == IPA_JF_CONST)
4425 struct ipa_cst_ref_desc *src_rdesc = jfunc_rdesc_usable (src_jf);
4427 if (!src_rdesc)
4428 dst_jf->value.constant.rdesc = NULL;
4429 else if (src->caller == dst->caller)
4431 /* Creation of a speculative edge. If the source edge is the one
4432 grabbing a reference, we must create a new (duplicate)
4433 reference description. Otherwise they refer to the same
4434 description corresponding to a reference taken in a function
4435 src->caller is inlined to. In that case we just must
4436 increment the refcount. */
4437 if (src_rdesc->cs == src)
4439 symtab_node *n = symtab_node_for_jfunc (src_jf);
4440 gcc_checking_assert (n);
4441 ipa_ref *ref
4442 = src->caller->find_reference (n, src->call_stmt,
4443 src->lto_stmt_uid);
4444 gcc_checking_assert (ref);
4445 dst->caller->clone_reference (ref, ref->stmt);
4447 ipa_cst_ref_desc *dst_rdesc = ipa_refdesc_pool.allocate ();
4448 dst_rdesc->cs = dst;
4449 dst_rdesc->refcount = src_rdesc->refcount;
4450 dst_rdesc->next_duplicate = NULL;
4451 dst_jf->value.constant.rdesc = dst_rdesc;
4453 else
4455 src_rdesc->refcount++;
4456 dst_jf->value.constant.rdesc = src_rdesc;
4459 else if (src_rdesc->cs == src)
4461 struct ipa_cst_ref_desc *dst_rdesc = ipa_refdesc_pool.allocate ();
4462 dst_rdesc->cs = dst;
4463 dst_rdesc->refcount = src_rdesc->refcount;
4464 dst_rdesc->next_duplicate = src_rdesc->next_duplicate;
4465 src_rdesc->next_duplicate = dst_rdesc;
4466 dst_jf->value.constant.rdesc = dst_rdesc;
4468 else
4470 struct ipa_cst_ref_desc *dst_rdesc;
4471 /* This can happen during inlining, when a JFUNC can refer to a
4472 reference taken in a function up in the tree of inline clones.
4473 We need to find the duplicate that refers to our tree of
4474 inline clones. */
4476 gcc_assert (dst->caller->inlined_to);
4477 for (dst_rdesc = src_rdesc->next_duplicate;
4478 dst_rdesc;
4479 dst_rdesc = dst_rdesc->next_duplicate)
4481 struct cgraph_node *top;
4482 top = dst_rdesc->cs->caller->inlined_to
4483 ? dst_rdesc->cs->caller->inlined_to
4484 : dst_rdesc->cs->caller;
4485 if (dst->caller->inlined_to == top)
4486 break;
4488 gcc_assert (dst_rdesc);
4489 dst_jf->value.constant.rdesc = dst_rdesc;
4492 else if (dst_jf->type == IPA_JF_PASS_THROUGH
4493 && src->caller == dst->caller)
4495 struct cgraph_node *inline_root = dst->caller->inlined_to
4496 ? dst->caller->inlined_to : dst->caller;
4497 ipa_node_params *root_info = ipa_node_params_sum->get (inline_root);
4498 int idx = ipa_get_jf_pass_through_formal_id (dst_jf);
4500 int c = ipa_get_controlled_uses (root_info, idx);
4501 if (c != IPA_UNDESCRIBED_USE)
4503 c++;
4504 ipa_set_controlled_uses (root_info, idx, c);
4510 /* Analyze newly added function into callgraph. */
4512 static void
4513 ipa_add_new_function (cgraph_node *node, void *data ATTRIBUTE_UNUSED)
4515 if (node->has_gimple_body_p ())
4516 ipa_analyze_node (node);
4519 /* Hook that is called by summary when a node is duplicated. */
4521 void
4522 ipa_node_params_t::duplicate(cgraph_node *src, cgraph_node *dst,
4523 ipa_node_params *old_info,
4524 ipa_node_params *new_info)
4526 ipa_agg_replacement_value *old_av, *new_av;
4528 new_info->descriptors = vec_safe_copy (old_info->descriptors);
4529 new_info->lattices = NULL;
4530 new_info->ipcp_orig_node = old_info->ipcp_orig_node;
4531 new_info->known_csts = old_info->known_csts.copy ();
4532 new_info->known_contexts = old_info->known_contexts.copy ();
4534 new_info->analysis_done = old_info->analysis_done;
4535 new_info->node_enqueued = old_info->node_enqueued;
4536 new_info->versionable = old_info->versionable;
4538 old_av = ipa_get_agg_replacements_for_node (src);
4539 if (old_av)
4541 new_av = NULL;
4542 while (old_av)
4544 struct ipa_agg_replacement_value *v;
4546 v = ggc_alloc<ipa_agg_replacement_value> ();
4547 memcpy (v, old_av, sizeof (*v));
4548 v->next = new_av;
4549 new_av = v;
4550 old_av = old_av->next;
4552 ipa_set_node_agg_value_chain (dst, new_av);
4556 /* Duplication of ipcp transformation summaries. */
4558 void
4559 ipcp_transformation_t::duplicate(cgraph_node *, cgraph_node *dst,
4560 ipcp_transformation *src_trans,
4561 ipcp_transformation *dst_trans)
4563 /* Avoid redundant work of duplicating vectors we will never use. */
4564 if (dst->inlined_to)
4565 return;
4566 dst_trans->bits = vec_safe_copy (src_trans->bits);
4567 dst_trans->m_vr = vec_safe_copy (src_trans->m_vr);
4568 ipa_agg_replacement_value *agg = src_trans->agg_values,
4569 **aggptr = &dst_trans->agg_values;
4570 while (agg)
4572 *aggptr = ggc_alloc<ipa_agg_replacement_value> ();
4573 **aggptr = *agg;
4574 agg = agg->next;
4575 aggptr = &(*aggptr)->next;
4579 /* Register our cgraph hooks if they are not already there. */
4581 void
4582 ipa_register_cgraph_hooks (void)
4584 ipa_check_create_node_params ();
4585 ipa_check_create_edge_args ();
4587 function_insertion_hook_holder =
4588 symtab->add_cgraph_insertion_hook (&ipa_add_new_function, NULL);
4591 /* Unregister our cgraph hooks if they are not already there. */
4593 static void
4594 ipa_unregister_cgraph_hooks (void)
4596 if (function_insertion_hook_holder)
4597 symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
4598 function_insertion_hook_holder = NULL;
4601 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
4602 longer needed after ipa-cp. */
4604 void
4605 ipa_free_all_structures_after_ipa_cp (void)
4607 if (!optimize && !in_lto_p)
4609 ipa_free_all_edge_args ();
4610 ipa_free_all_node_params ();
4611 ipcp_sources_pool.release ();
4612 ipcp_cst_values_pool.release ();
4613 ipcp_poly_ctx_values_pool.release ();
4614 ipcp_agg_lattice_pool.release ();
4615 ipa_unregister_cgraph_hooks ();
4616 ipa_refdesc_pool.release ();
4620 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
4621 longer needed after indirect inlining. */
4623 void
4624 ipa_free_all_structures_after_iinln (void)
4626 ipa_free_all_edge_args ();
4627 ipa_free_all_node_params ();
4628 ipa_unregister_cgraph_hooks ();
4629 ipcp_sources_pool.release ();
4630 ipcp_cst_values_pool.release ();
4631 ipcp_poly_ctx_values_pool.release ();
4632 ipcp_agg_lattice_pool.release ();
4633 ipa_refdesc_pool.release ();
4636 /* Print ipa_tree_map data structures of all functions in the
4637 callgraph to F. */
4639 void
4640 ipa_print_node_params (FILE *f, struct cgraph_node *node)
4642 int i, count;
4643 class ipa_node_params *info;
4645 if (!node->definition)
4646 return;
4647 info = ipa_node_params_sum->get (node);
4648 fprintf (f, " function %s parameter descriptors:\n", node->dump_name ());
4649 if (!info)
4651 fprintf (f, " no params return\n");
4652 return;
4654 count = ipa_get_param_count (info);
4655 for (i = 0; i < count; i++)
4657 int c;
4659 fprintf (f, " ");
4660 ipa_dump_param (f, info, i);
4661 if (ipa_is_param_used (info, i))
4662 fprintf (f, " used");
4663 if (ipa_is_param_used_by_ipa_predicates (info, i))
4664 fprintf (f, " used_by_ipa_predicates");
4665 if (ipa_is_param_used_by_indirect_call (info, i))
4666 fprintf (f, " used_by_indirect_call");
4667 if (ipa_is_param_used_by_polymorphic_call (info, i))
4668 fprintf (f, " used_by_polymorphic_call");
4669 c = ipa_get_controlled_uses (info, i);
4670 if (c == IPA_UNDESCRIBED_USE)
4671 fprintf (f, " undescribed_use");
4672 else
4673 fprintf (f, " controlled_uses=%i %s", c,
4674 ipa_get_param_load_dereferenced (info, i)
4675 ? "(load_dereferenced)" : "");
4676 fprintf (f, "\n");
4680 /* Print ipa_tree_map data structures of all functions in the
4681 callgraph to F. */
4683 void
4684 ipa_print_all_params (FILE * f)
4686 struct cgraph_node *node;
4688 fprintf (f, "\nFunction parameters:\n");
4689 FOR_EACH_FUNCTION (node)
4690 ipa_print_node_params (f, node);
4693 /* Dump the AV linked list. */
4695 void
4696 ipa_dump_agg_replacement_values (FILE *f, struct ipa_agg_replacement_value *av)
4698 bool comma = false;
4699 fprintf (f, " Aggregate replacements:");
4700 for (; av; av = av->next)
4702 fprintf (f, "%s %i[" HOST_WIDE_INT_PRINT_DEC "]=", comma ? "," : "",
4703 av->index, av->offset);
4704 print_generic_expr (f, av->value);
4705 comma = true;
4707 fprintf (f, "\n");
4710 /* Stream out jump function JUMP_FUNC to OB. */
4712 static void
4713 ipa_write_jump_function (struct output_block *ob,
4714 struct ipa_jump_func *jump_func)
4716 struct ipa_agg_jf_item *item;
4717 struct bitpack_d bp;
4718 int i, count;
4719 int flag = 0;
4721 /* ADDR_EXPRs are very comon IP invariants; save some streamer data
4722 as well as WPA memory by handling them specially. */
4723 if (jump_func->type == IPA_JF_CONST
4724 && TREE_CODE (jump_func->value.constant.value) == ADDR_EXPR)
4725 flag = 1;
4727 streamer_write_uhwi (ob, jump_func->type * 2 + flag);
4728 switch (jump_func->type)
4730 case IPA_JF_UNKNOWN:
4731 break;
4732 case IPA_JF_CONST:
4733 gcc_assert (
4734 EXPR_LOCATION (jump_func->value.constant.value) == UNKNOWN_LOCATION);
4735 stream_write_tree (ob,
4736 flag
4737 ? TREE_OPERAND (jump_func->value.constant.value, 0)
4738 : jump_func->value.constant.value, true);
4739 break;
4740 case IPA_JF_PASS_THROUGH:
4741 streamer_write_uhwi (ob, jump_func->value.pass_through.operation);
4742 if (jump_func->value.pass_through.operation == NOP_EXPR)
4744 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4745 bp = bitpack_create (ob->main_stream);
4746 bp_pack_value (&bp, jump_func->value.pass_through.agg_preserved, 1);
4747 streamer_write_bitpack (&bp);
4749 else if (TREE_CODE_CLASS (jump_func->value.pass_through.operation)
4750 == tcc_unary)
4751 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4752 else
4754 stream_write_tree (ob, jump_func->value.pass_through.operand, true);
4755 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4757 break;
4758 case IPA_JF_ANCESTOR:
4759 streamer_write_uhwi (ob, jump_func->value.ancestor.offset);
4760 streamer_write_uhwi (ob, jump_func->value.ancestor.formal_id);
4761 bp = bitpack_create (ob->main_stream);
4762 bp_pack_value (&bp, jump_func->value.ancestor.agg_preserved, 1);
4763 streamer_write_bitpack (&bp);
4764 break;
4765 default:
4766 fatal_error (UNKNOWN_LOCATION, "invalid jump function in LTO stream");
4769 count = vec_safe_length (jump_func->agg.items);
4770 streamer_write_uhwi (ob, count);
4771 if (count)
4773 bp = bitpack_create (ob->main_stream);
4774 bp_pack_value (&bp, jump_func->agg.by_ref, 1);
4775 streamer_write_bitpack (&bp);
4778 FOR_EACH_VEC_SAFE_ELT (jump_func->agg.items, i, item)
4780 stream_write_tree (ob, item->type, true);
4781 streamer_write_uhwi (ob, item->offset);
4782 streamer_write_uhwi (ob, item->jftype);
4783 switch (item->jftype)
4785 case IPA_JF_UNKNOWN:
4786 break;
4787 case IPA_JF_CONST:
4788 stream_write_tree (ob, item->value.constant, true);
4789 break;
4790 case IPA_JF_PASS_THROUGH:
4791 case IPA_JF_LOAD_AGG:
4792 streamer_write_uhwi (ob, item->value.pass_through.operation);
4793 streamer_write_uhwi (ob, item->value.pass_through.formal_id);
4794 if (TREE_CODE_CLASS (item->value.pass_through.operation)
4795 != tcc_unary)
4796 stream_write_tree (ob, item->value.pass_through.operand, true);
4797 if (item->jftype == IPA_JF_LOAD_AGG)
4799 stream_write_tree (ob, item->value.load_agg.type, true);
4800 streamer_write_uhwi (ob, item->value.load_agg.offset);
4801 bp = bitpack_create (ob->main_stream);
4802 bp_pack_value (&bp, item->value.load_agg.by_ref, 1);
4803 streamer_write_bitpack (&bp);
4805 break;
4806 default:
4807 fatal_error (UNKNOWN_LOCATION,
4808 "invalid jump function in LTO stream");
4812 bp = bitpack_create (ob->main_stream);
4813 bp_pack_value (&bp, !!jump_func->bits, 1);
4814 streamer_write_bitpack (&bp);
4815 if (jump_func->bits)
4817 streamer_write_widest_int (ob, jump_func->bits->value);
4818 streamer_write_widest_int (ob, jump_func->bits->mask);
4820 bp_pack_value (&bp, !!jump_func->m_vr, 1);
4821 streamer_write_bitpack (&bp);
4822 if (jump_func->m_vr)
4824 streamer_write_enum (ob->main_stream, value_rang_type,
4825 VR_LAST, jump_func->m_vr->kind ());
4826 stream_write_tree (ob, jump_func->m_vr->min (), true);
4827 stream_write_tree (ob, jump_func->m_vr->max (), true);
4831 /* Read in jump function JUMP_FUNC from IB. */
4833 static void
4834 ipa_read_jump_function (class lto_input_block *ib,
4835 struct ipa_jump_func *jump_func,
4836 struct cgraph_edge *cs,
4837 class data_in *data_in,
4838 bool prevails)
4840 enum jump_func_type jftype;
4841 enum tree_code operation;
4842 int i, count;
4843 int val = streamer_read_uhwi (ib);
4844 bool flag = val & 1;
4846 jftype = (enum jump_func_type) (val / 2);
4847 switch (jftype)
4849 case IPA_JF_UNKNOWN:
4850 ipa_set_jf_unknown (jump_func);
4851 break;
4852 case IPA_JF_CONST:
4854 tree t = stream_read_tree (ib, data_in);
4855 if (flag && prevails)
4856 t = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
4857 ipa_set_jf_constant (jump_func, t, cs);
4859 break;
4860 case IPA_JF_PASS_THROUGH:
4861 operation = (enum tree_code) streamer_read_uhwi (ib);
4862 if (operation == NOP_EXPR)
4864 int formal_id = streamer_read_uhwi (ib);
4865 struct bitpack_d bp = streamer_read_bitpack (ib);
4866 bool agg_preserved = bp_unpack_value (&bp, 1);
4867 ipa_set_jf_simple_pass_through (jump_func, formal_id, agg_preserved);
4869 else if (TREE_CODE_CLASS (operation) == tcc_unary)
4871 int formal_id = streamer_read_uhwi (ib);
4872 ipa_set_jf_unary_pass_through (jump_func, formal_id, operation);
4874 else
4876 tree operand = stream_read_tree (ib, data_in);
4877 int formal_id = streamer_read_uhwi (ib);
4878 ipa_set_jf_arith_pass_through (jump_func, formal_id, operand,
4879 operation);
4881 break;
4882 case IPA_JF_ANCESTOR:
4884 HOST_WIDE_INT offset = streamer_read_uhwi (ib);
4885 int formal_id = streamer_read_uhwi (ib);
4886 struct bitpack_d bp = streamer_read_bitpack (ib);
4887 bool agg_preserved = bp_unpack_value (&bp, 1);
4888 ipa_set_ancestor_jf (jump_func, offset, formal_id, agg_preserved);
4889 break;
4891 default:
4892 fatal_error (UNKNOWN_LOCATION, "invalid jump function in LTO stream");
4895 count = streamer_read_uhwi (ib);
4896 if (prevails)
4898 jump_func->agg.items = NULL;
4899 vec_safe_reserve (jump_func->agg.items, count, true);
4901 if (count)
4903 struct bitpack_d bp = streamer_read_bitpack (ib);
4904 jump_func->agg.by_ref = bp_unpack_value (&bp, 1);
4906 for (i = 0; i < count; i++)
4908 struct ipa_agg_jf_item item;
4909 item.type = stream_read_tree (ib, data_in);
4910 item.offset = streamer_read_uhwi (ib);
4911 item.jftype = (enum jump_func_type) streamer_read_uhwi (ib);
4913 switch (item.jftype)
4915 case IPA_JF_UNKNOWN:
4916 break;
4917 case IPA_JF_CONST:
4918 item.value.constant = stream_read_tree (ib, data_in);
4919 break;
4920 case IPA_JF_PASS_THROUGH:
4921 case IPA_JF_LOAD_AGG:
4922 operation = (enum tree_code) streamer_read_uhwi (ib);
4923 item.value.pass_through.operation = operation;
4924 item.value.pass_through.formal_id = streamer_read_uhwi (ib);
4925 if (TREE_CODE_CLASS (operation) == tcc_unary)
4926 item.value.pass_through.operand = NULL_TREE;
4927 else
4928 item.value.pass_through.operand = stream_read_tree (ib, data_in);
4929 if (item.jftype == IPA_JF_LOAD_AGG)
4931 struct bitpack_d bp;
4932 item.value.load_agg.type = stream_read_tree (ib, data_in);
4933 item.value.load_agg.offset = streamer_read_uhwi (ib);
4934 bp = streamer_read_bitpack (ib);
4935 item.value.load_agg.by_ref = bp_unpack_value (&bp, 1);
4937 break;
4938 default:
4939 fatal_error (UNKNOWN_LOCATION,
4940 "invalid jump function in LTO stream");
4942 if (prevails)
4943 jump_func->agg.items->quick_push (item);
4946 struct bitpack_d bp = streamer_read_bitpack (ib);
4947 bool bits_known = bp_unpack_value (&bp, 1);
4948 if (bits_known)
4950 widest_int value = streamer_read_widest_int (ib);
4951 widest_int mask = streamer_read_widest_int (ib);
4952 if (prevails)
4953 ipa_set_jfunc_bits (jump_func, value, mask);
4955 else
4956 jump_func->bits = NULL;
4958 struct bitpack_d vr_bp = streamer_read_bitpack (ib);
4959 bool vr_known = bp_unpack_value (&vr_bp, 1);
4960 if (vr_known)
4962 enum value_range_kind type = streamer_read_enum (ib, value_range_kind,
4963 VR_LAST);
4964 tree min = stream_read_tree (ib, data_in);
4965 tree max = stream_read_tree (ib, data_in);
4966 if (prevails)
4967 ipa_set_jfunc_vr (jump_func, type, min, max);
4969 else
4970 jump_func->m_vr = NULL;
4973 /* Stream out parts of cgraph_indirect_call_info corresponding to CS that are
4974 relevant to indirect inlining to OB. */
4976 static void
4977 ipa_write_indirect_edge_info (struct output_block *ob,
4978 struct cgraph_edge *cs)
4980 class cgraph_indirect_call_info *ii = cs->indirect_info;
4981 struct bitpack_d bp;
4983 streamer_write_hwi (ob, ii->param_index);
4984 bp = bitpack_create (ob->main_stream);
4985 bp_pack_value (&bp, ii->polymorphic, 1);
4986 bp_pack_value (&bp, ii->agg_contents, 1);
4987 bp_pack_value (&bp, ii->member_ptr, 1);
4988 bp_pack_value (&bp, ii->by_ref, 1);
4989 bp_pack_value (&bp, ii->guaranteed_unmodified, 1);
4990 bp_pack_value (&bp, ii->vptr_changed, 1);
4991 streamer_write_bitpack (&bp);
4992 if (ii->agg_contents || ii->polymorphic)
4993 streamer_write_hwi (ob, ii->offset);
4994 else
4995 gcc_assert (ii->offset == 0);
4997 if (ii->polymorphic)
4999 streamer_write_hwi (ob, ii->otr_token);
5000 stream_write_tree (ob, ii->otr_type, true);
5001 ii->context.stream_out (ob);
5005 /* Read in parts of cgraph_indirect_call_info corresponding to CS that are
5006 relevant to indirect inlining from IB. */
5008 static void
5009 ipa_read_indirect_edge_info (class lto_input_block *ib,
5010 class data_in *data_in,
5011 struct cgraph_edge *cs,
5012 class ipa_node_params *info)
5014 class cgraph_indirect_call_info *ii = cs->indirect_info;
5015 struct bitpack_d bp;
5017 ii->param_index = (int) streamer_read_hwi (ib);
5018 bp = streamer_read_bitpack (ib);
5019 ii->polymorphic = bp_unpack_value (&bp, 1);
5020 ii->agg_contents = bp_unpack_value (&bp, 1);
5021 ii->member_ptr = bp_unpack_value (&bp, 1);
5022 ii->by_ref = bp_unpack_value (&bp, 1);
5023 ii->guaranteed_unmodified = bp_unpack_value (&bp, 1);
5024 ii->vptr_changed = bp_unpack_value (&bp, 1);
5025 if (ii->agg_contents || ii->polymorphic)
5026 ii->offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
5027 else
5028 ii->offset = 0;
5029 if (ii->polymorphic)
5031 ii->otr_token = (HOST_WIDE_INT) streamer_read_hwi (ib);
5032 ii->otr_type = stream_read_tree (ib, data_in);
5033 ii->context.stream_in (ib, data_in);
5035 if (info && ii->param_index >= 0)
5037 if (ii->polymorphic)
5038 ipa_set_param_used_by_polymorphic_call (info,
5039 ii->param_index , true);
5040 ipa_set_param_used_by_indirect_call (info,
5041 ii->param_index, true);
5045 /* Stream out NODE info to OB. */
5047 static void
5048 ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
5050 int node_ref;
5051 lto_symtab_encoder_t encoder;
5052 ipa_node_params *info = ipa_node_params_sum->get (node);
5053 int j;
5054 struct cgraph_edge *e;
5055 struct bitpack_d bp;
5057 encoder = ob->decl_state->symtab_node_encoder;
5058 node_ref = lto_symtab_encoder_encode (encoder, node);
5059 streamer_write_uhwi (ob, node_ref);
5061 streamer_write_uhwi (ob, ipa_get_param_count (info));
5062 for (j = 0; j < ipa_get_param_count (info); j++)
5063 streamer_write_uhwi (ob, ipa_get_param_move_cost (info, j));
5064 bp = bitpack_create (ob->main_stream);
5065 gcc_assert (info->analysis_done
5066 || ipa_get_param_count (info) == 0);
5067 gcc_assert (!info->node_enqueued);
5068 gcc_assert (!info->ipcp_orig_node);
5069 for (j = 0; j < ipa_get_param_count (info); j++)
5071 /* TODO: We could just not stream the bit in the undescribed case. */
5072 bool d = (ipa_get_controlled_uses (info, j) != IPA_UNDESCRIBED_USE)
5073 ? ipa_get_param_load_dereferenced (info, j) : true;
5074 bp_pack_value (&bp, d, 1);
5075 bp_pack_value (&bp, ipa_is_param_used (info, j), 1);
5077 streamer_write_bitpack (&bp);
5078 for (j = 0; j < ipa_get_param_count (info); j++)
5080 streamer_write_hwi (ob, ipa_get_controlled_uses (info, j));
5081 stream_write_tree (ob, ipa_get_type (info, j), true);
5083 for (e = node->callees; e; e = e->next_callee)
5085 ipa_edge_args *args = ipa_edge_args_sum->get (e);
5087 if (!args)
5089 streamer_write_uhwi (ob, 0);
5090 continue;
5093 streamer_write_uhwi (ob,
5094 ipa_get_cs_argument_count (args) * 2
5095 + (args->polymorphic_call_contexts != NULL));
5096 for (j = 0; j < ipa_get_cs_argument_count (args); j++)
5098 ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
5099 if (args->polymorphic_call_contexts != NULL)
5100 ipa_get_ith_polymorhic_call_context (args, j)->stream_out (ob);
5103 for (e = node->indirect_calls; e; e = e->next_callee)
5105 ipa_edge_args *args = ipa_edge_args_sum->get (e);
5106 if (!args)
5107 streamer_write_uhwi (ob, 0);
5108 else
5110 streamer_write_uhwi (ob,
5111 ipa_get_cs_argument_count (args) * 2
5112 + (args->polymorphic_call_contexts != NULL));
5113 for (j = 0; j < ipa_get_cs_argument_count (args); j++)
5115 ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
5116 if (args->polymorphic_call_contexts != NULL)
5117 ipa_get_ith_polymorhic_call_context (args, j)->stream_out (ob);
5120 ipa_write_indirect_edge_info (ob, e);
5124 /* Stream in edge E from IB. */
5126 static void
5127 ipa_read_edge_info (class lto_input_block *ib,
5128 class data_in *data_in,
5129 struct cgraph_edge *e, bool prevails)
5131 int count = streamer_read_uhwi (ib);
5132 bool contexts_computed = count & 1;
5134 count /= 2;
5135 if (!count)
5136 return;
5137 if (prevails
5138 && (e->possibly_call_in_translation_unit_p ()
5139 /* Also stream in jump functions to builtins in hope that they
5140 will get fnspecs. */
5141 || fndecl_built_in_p (e->callee->decl, BUILT_IN_NORMAL)))
5143 ipa_edge_args *args = ipa_edge_args_sum->get_create (e);
5144 vec_safe_grow_cleared (args->jump_functions, count, true);
5145 if (contexts_computed)
5146 vec_safe_grow_cleared (args->polymorphic_call_contexts, count, true);
5147 for (int k = 0; k < count; k++)
5149 ipa_read_jump_function (ib, ipa_get_ith_jump_func (args, k), e,
5150 data_in, prevails);
5151 if (contexts_computed)
5152 ipa_get_ith_polymorhic_call_context (args, k)->stream_in
5153 (ib, data_in);
5156 else
5158 for (int k = 0; k < count; k++)
5160 struct ipa_jump_func dummy;
5161 ipa_read_jump_function (ib, &dummy, e,
5162 data_in, prevails);
5163 if (contexts_computed)
5165 class ipa_polymorphic_call_context ctx;
5166 ctx.stream_in (ib, data_in);
5172 /* Stream in NODE info from IB. */
5174 static void
5175 ipa_read_node_info (class lto_input_block *ib, struct cgraph_node *node,
5176 class data_in *data_in)
5178 int k;
5179 struct cgraph_edge *e;
5180 struct bitpack_d bp;
5181 bool prevails = node->prevailing_p ();
5182 ipa_node_params *info
5183 = prevails ? ipa_node_params_sum->get_create (node) : NULL;
5185 int param_count = streamer_read_uhwi (ib);
5186 if (prevails)
5188 ipa_alloc_node_params (node, param_count);
5189 for (k = 0; k < param_count; k++)
5190 (*info->descriptors)[k].move_cost = streamer_read_uhwi (ib);
5191 if (ipa_get_param_count (info) != 0)
5192 info->analysis_done = true;
5193 info->node_enqueued = false;
5195 else
5196 for (k = 0; k < param_count; k++)
5197 streamer_read_uhwi (ib);
5199 bp = streamer_read_bitpack (ib);
5200 for (k = 0; k < param_count; k++)
5202 bool load_dereferenced = bp_unpack_value (&bp, 1);
5203 bool used = bp_unpack_value (&bp, 1);
5205 if (prevails)
5207 ipa_set_param_load_dereferenced (info, k, load_dereferenced);
5208 ipa_set_param_used (info, k, used);
5211 for (k = 0; k < param_count; k++)
5213 int nuses = streamer_read_hwi (ib);
5214 tree type = stream_read_tree (ib, data_in);
5216 if (prevails)
5218 ipa_set_controlled_uses (info, k, nuses);
5219 (*info->descriptors)[k].decl_or_type = type;
5222 for (e = node->callees; e; e = e->next_callee)
5223 ipa_read_edge_info (ib, data_in, e, prevails);
5224 for (e = node->indirect_calls; e; e = e->next_callee)
5226 ipa_read_edge_info (ib, data_in, e, prevails);
5227 ipa_read_indirect_edge_info (ib, data_in, e, info);
5231 /* Write jump functions for nodes in SET. */
5233 void
5234 ipa_prop_write_jump_functions (void)
5236 struct output_block *ob;
5237 unsigned int count = 0;
5238 lto_symtab_encoder_iterator lsei;
5239 lto_symtab_encoder_t encoder;
5241 if (!ipa_node_params_sum || !ipa_edge_args_sum)
5242 return;
5244 ob = create_output_block (LTO_section_jump_functions);
5245 encoder = ob->decl_state->symtab_node_encoder;
5246 ob->symbol = NULL;
5247 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
5248 lsei_next_function_in_partition (&lsei))
5250 cgraph_node *node = lsei_cgraph_node (lsei);
5251 if (node->has_gimple_body_p ()
5252 && ipa_node_params_sum->get (node) != NULL)
5253 count++;
5256 streamer_write_uhwi (ob, count);
5258 /* Process all of the functions. */
5259 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
5260 lsei_next_function_in_partition (&lsei))
5262 cgraph_node *node = lsei_cgraph_node (lsei);
5263 if (node->has_gimple_body_p ()
5264 && ipa_node_params_sum->get (node) != NULL)
5265 ipa_write_node_info (ob, node);
5267 streamer_write_char_stream (ob->main_stream, 0);
5268 produce_asm (ob, NULL);
5269 destroy_output_block (ob);
5272 /* Read section in file FILE_DATA of length LEN with data DATA. */
5274 static void
5275 ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
5276 size_t len)
5278 const struct lto_function_header *header =
5279 (const struct lto_function_header *) data;
5280 const int cfg_offset = sizeof (struct lto_function_header);
5281 const int main_offset = cfg_offset + header->cfg_size;
5282 const int string_offset = main_offset + header->main_size;
5283 class data_in *data_in;
5284 unsigned int i;
5285 unsigned int count;
5287 lto_input_block ib_main ((const char *) data + main_offset,
5288 header->main_size, file_data->mode_table);
5290 data_in =
5291 lto_data_in_create (file_data, (const char *) data + string_offset,
5292 header->string_size, vNULL);
5293 count = streamer_read_uhwi (&ib_main);
5295 for (i = 0; i < count; i++)
5297 unsigned int index;
5298 struct cgraph_node *node;
5299 lto_symtab_encoder_t encoder;
5301 index = streamer_read_uhwi (&ib_main);
5302 encoder = file_data->symtab_node_encoder;
5303 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
5304 index));
5305 gcc_assert (node->definition);
5306 ipa_read_node_info (&ib_main, node, data_in);
5308 lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
5309 len);
5310 lto_data_in_delete (data_in);
5313 /* Read ipcp jump functions. */
5315 void
5316 ipa_prop_read_jump_functions (void)
5318 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
5319 struct lto_file_decl_data *file_data;
5320 unsigned int j = 0;
5322 ipa_check_create_node_params ();
5323 ipa_check_create_edge_args ();
5324 ipa_register_cgraph_hooks ();
5326 while ((file_data = file_data_vec[j++]))
5328 size_t len;
5329 const char *data
5330 = lto_get_summary_section_data (file_data, LTO_section_jump_functions,
5331 &len);
5332 if (data)
5333 ipa_prop_read_section (file_data, data, len);
5337 void
5338 write_ipcp_transformation_info (output_block *ob, cgraph_node *node)
5340 int node_ref;
5341 unsigned int count = 0;
5342 lto_symtab_encoder_t encoder;
5343 struct ipa_agg_replacement_value *aggvals, *av;
5345 aggvals = ipa_get_agg_replacements_for_node (node);
5346 encoder = ob->decl_state->symtab_node_encoder;
5347 node_ref = lto_symtab_encoder_encode (encoder, node);
5348 streamer_write_uhwi (ob, node_ref);
5350 for (av = aggvals; av; av = av->next)
5351 count++;
5352 streamer_write_uhwi (ob, count);
5354 for (av = aggvals; av; av = av->next)
5356 struct bitpack_d bp;
5358 streamer_write_uhwi (ob, av->offset);
5359 streamer_write_uhwi (ob, av->index);
5360 stream_write_tree (ob, av->value, true);
5362 bp = bitpack_create (ob->main_stream);
5363 bp_pack_value (&bp, av->by_ref, 1);
5364 streamer_write_bitpack (&bp);
5367 ipcp_transformation *ts = ipcp_get_transformation_summary (node);
5368 if (ts && vec_safe_length (ts->m_vr) > 0)
5370 count = ts->m_vr->length ();
5371 streamer_write_uhwi (ob, count);
5372 for (unsigned i = 0; i < count; ++i)
5374 struct bitpack_d bp;
5375 ipa_vr *parm_vr = &(*ts->m_vr)[i];
5376 bp = bitpack_create (ob->main_stream);
5377 bp_pack_value (&bp, parm_vr->known, 1);
5378 streamer_write_bitpack (&bp);
5379 if (parm_vr->known)
5381 streamer_write_enum (ob->main_stream, value_rang_type,
5382 VR_LAST, parm_vr->type);
5383 streamer_write_wide_int (ob, parm_vr->min);
5384 streamer_write_wide_int (ob, parm_vr->max);
5388 else
5389 streamer_write_uhwi (ob, 0);
5391 if (ts && vec_safe_length (ts->bits) > 0)
5393 count = ts->bits->length ();
5394 streamer_write_uhwi (ob, count);
5396 for (unsigned i = 0; i < count; ++i)
5398 const ipa_bits *bits_jfunc = (*ts->bits)[i];
5399 struct bitpack_d bp = bitpack_create (ob->main_stream);
5400 bp_pack_value (&bp, !!bits_jfunc, 1);
5401 streamer_write_bitpack (&bp);
5402 if (bits_jfunc)
5404 streamer_write_widest_int (ob, bits_jfunc->value);
5405 streamer_write_widest_int (ob, bits_jfunc->mask);
5409 else
5410 streamer_write_uhwi (ob, 0);
5413 /* Stream in the aggregate value replacement chain for NODE from IB. */
5415 static void
5416 read_ipcp_transformation_info (lto_input_block *ib, cgraph_node *node,
5417 data_in *data_in)
5419 struct ipa_agg_replacement_value *aggvals = NULL;
5420 unsigned int count, i;
5422 count = streamer_read_uhwi (ib);
5423 for (i = 0; i <count; i++)
5425 struct ipa_agg_replacement_value *av;
5426 struct bitpack_d bp;
5428 av = ggc_alloc<ipa_agg_replacement_value> ();
5429 av->offset = streamer_read_uhwi (ib);
5430 av->index = streamer_read_uhwi (ib);
5431 av->value = stream_read_tree (ib, data_in);
5432 bp = streamer_read_bitpack (ib);
5433 av->by_ref = bp_unpack_value (&bp, 1);
5434 av->next = aggvals;
5435 aggvals = av;
5437 ipa_set_node_agg_value_chain (node, aggvals);
5439 count = streamer_read_uhwi (ib);
5440 if (count > 0)
5442 ipcp_transformation_initialize ();
5443 ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
5444 vec_safe_grow_cleared (ts->m_vr, count, true);
5445 for (i = 0; i < count; i++)
5447 ipa_vr *parm_vr;
5448 parm_vr = &(*ts->m_vr)[i];
5449 struct bitpack_d bp;
5450 bp = streamer_read_bitpack (ib);
5451 parm_vr->known = bp_unpack_value (&bp, 1);
5452 if (parm_vr->known)
5454 parm_vr->type = streamer_read_enum (ib, value_range_kind,
5455 VR_LAST);
5456 parm_vr->min = streamer_read_wide_int (ib);
5457 parm_vr->max = streamer_read_wide_int (ib);
5461 count = streamer_read_uhwi (ib);
5462 if (count > 0)
5464 ipcp_transformation_initialize ();
5465 ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
5466 vec_safe_grow_cleared (ts->bits, count, true);
5468 for (i = 0; i < count; i++)
5470 struct bitpack_d bp = streamer_read_bitpack (ib);
5471 bool known = bp_unpack_value (&bp, 1);
5472 if (known)
5474 const widest_int value = streamer_read_widest_int (ib);
5475 const widest_int mask = streamer_read_widest_int (ib);
5476 ipa_bits *bits
5477 = ipa_get_ipa_bits_for_value (value, mask);
5478 (*ts->bits)[i] = bits;
5484 /* Write all aggregate replacement for nodes in set. */
5486 void
5487 ipcp_write_transformation_summaries (void)
5489 struct cgraph_node *node;
5490 struct output_block *ob;
5491 unsigned int count = 0;
5492 lto_symtab_encoder_iterator lsei;
5493 lto_symtab_encoder_t encoder;
5495 ob = create_output_block (LTO_section_ipcp_transform);
5496 encoder = ob->decl_state->symtab_node_encoder;
5497 ob->symbol = NULL;
5498 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
5499 lsei_next_function_in_partition (&lsei))
5501 node = lsei_cgraph_node (lsei);
5502 if (node->has_gimple_body_p ())
5503 count++;
5506 streamer_write_uhwi (ob, count);
5508 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
5509 lsei_next_function_in_partition (&lsei))
5511 node = lsei_cgraph_node (lsei);
5512 if (node->has_gimple_body_p ())
5513 write_ipcp_transformation_info (ob, node);
5515 streamer_write_char_stream (ob->main_stream, 0);
5516 produce_asm (ob, NULL);
5517 destroy_output_block (ob);
5520 /* Read replacements section in file FILE_DATA of length LEN with data
5521 DATA. */
5523 static void
5524 read_replacements_section (struct lto_file_decl_data *file_data,
5525 const char *data,
5526 size_t len)
5528 const struct lto_function_header *header =
5529 (const struct lto_function_header *) data;
5530 const int cfg_offset = sizeof (struct lto_function_header);
5531 const int main_offset = cfg_offset + header->cfg_size;
5532 const int string_offset = main_offset + header->main_size;
5533 class data_in *data_in;
5534 unsigned int i;
5535 unsigned int count;
5537 lto_input_block ib_main ((const char *) data + main_offset,
5538 header->main_size, file_data->mode_table);
5540 data_in = lto_data_in_create (file_data, (const char *) data + string_offset,
5541 header->string_size, vNULL);
5542 count = streamer_read_uhwi (&ib_main);
5544 for (i = 0; i < count; i++)
5546 unsigned int index;
5547 struct cgraph_node *node;
5548 lto_symtab_encoder_t encoder;
5550 index = streamer_read_uhwi (&ib_main);
5551 encoder = file_data->symtab_node_encoder;
5552 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
5553 index));
5554 gcc_assert (node->definition);
5555 read_ipcp_transformation_info (&ib_main, node, data_in);
5557 lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
5558 len);
5559 lto_data_in_delete (data_in);
5562 /* Read IPA-CP aggregate replacements. */
5564 void
5565 ipcp_read_transformation_summaries (void)
5567 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
5568 struct lto_file_decl_data *file_data;
5569 unsigned int j = 0;
5571 while ((file_data = file_data_vec[j++]))
5573 size_t len;
5574 const char *data
5575 = lto_get_summary_section_data (file_data, LTO_section_ipcp_transform,
5576 &len);
5577 if (data)
5578 read_replacements_section (file_data, data, len);
5582 /* Adjust the aggregate replacements in AGGVAL to reflect parameters skipped in
5583 NODE. */
5585 static void
5586 adjust_agg_replacement_values (struct cgraph_node *node,
5587 struct ipa_agg_replacement_value *aggval)
5589 struct ipa_agg_replacement_value *v;
5590 clone_info *cinfo = clone_info::get (node);
5592 if (!cinfo || !cinfo->param_adjustments)
5593 return;
5595 auto_vec<int, 16> new_indices;
5596 cinfo->param_adjustments->get_updated_indices (&new_indices);
5597 for (v = aggval; v; v = v->next)
5599 gcc_checking_assert (v->index >= 0);
5601 if ((unsigned) v->index < new_indices.length ())
5602 v->index = new_indices[v->index];
5603 else
5604 /* This can happen if we know about a constant passed by reference by
5605 an argument which is never actually used for anything, let alone
5606 loading that constant. */
5607 v->index = -1;
5611 /* Dominator walker driving the ipcp modification phase. */
5613 class ipcp_modif_dom_walker : public dom_walker
5615 public:
5616 ipcp_modif_dom_walker (struct ipa_func_body_info *fbi,
5617 vec<ipa_param_descriptor, va_gc> *descs,
5618 struct ipa_agg_replacement_value *av,
5619 bool *sc)
5620 : dom_walker (CDI_DOMINATORS), m_fbi (fbi), m_descriptors (descs),
5621 m_aggval (av), m_something_changed (sc) {}
5623 virtual edge before_dom_children (basic_block);
5624 bool cleanup_eh ()
5625 { return gimple_purge_all_dead_eh_edges (m_need_eh_cleanup); }
5627 private:
5628 struct ipa_func_body_info *m_fbi;
5629 vec<ipa_param_descriptor, va_gc> *m_descriptors;
5630 struct ipa_agg_replacement_value *m_aggval;
5631 bool *m_something_changed;
5632 auto_bitmap m_need_eh_cleanup;
5635 edge
5636 ipcp_modif_dom_walker::before_dom_children (basic_block bb)
5638 gimple_stmt_iterator gsi;
5639 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
5641 struct ipa_agg_replacement_value *v;
5642 gimple *stmt = gsi_stmt (gsi);
5643 tree rhs, val, t;
5644 HOST_WIDE_INT offset;
5645 poly_int64 size;
5646 int index;
5647 bool by_ref, vce;
5649 if (!gimple_assign_load_p (stmt))
5650 continue;
5651 rhs = gimple_assign_rhs1 (stmt);
5652 if (!is_gimple_reg_type (TREE_TYPE (rhs)))
5653 continue;
5655 vce = false;
5656 t = rhs;
5657 while (handled_component_p (t))
5659 /* V_C_E can do things like convert an array of integers to one
5660 bigger integer and similar things we do not handle below. */
5661 if (TREE_CODE (t) == VIEW_CONVERT_EXPR)
5663 vce = true;
5664 break;
5666 t = TREE_OPERAND (t, 0);
5668 if (vce)
5669 continue;
5671 if (!ipa_load_from_parm_agg (m_fbi, m_descriptors, stmt, rhs, &index,
5672 &offset, &size, &by_ref))
5673 continue;
5674 for (v = m_aggval; v; v = v->next)
5675 if (v->index == index
5676 && v->offset == offset)
5677 break;
5678 if (!v
5679 || v->by_ref != by_ref
5680 || maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (v->value))),
5681 size))
5682 continue;
5684 gcc_checking_assert (is_gimple_ip_invariant (v->value));
5685 if (!useless_type_conversion_p (TREE_TYPE (rhs), TREE_TYPE (v->value)))
5687 if (fold_convertible_p (TREE_TYPE (rhs), v->value))
5688 val = fold_build1 (NOP_EXPR, TREE_TYPE (rhs), v->value);
5689 else if (TYPE_SIZE (TREE_TYPE (rhs))
5690 == TYPE_SIZE (TREE_TYPE (v->value)))
5691 val = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (rhs), v->value);
5692 else
5694 if (dump_file)
5696 fprintf (dump_file, " const ");
5697 print_generic_expr (dump_file, v->value);
5698 fprintf (dump_file, " can't be converted to type of ");
5699 print_generic_expr (dump_file, rhs);
5700 fprintf (dump_file, "\n");
5702 continue;
5705 else
5706 val = v->value;
5708 if (dump_file && (dump_flags & TDF_DETAILS))
5710 fprintf (dump_file, "Modifying stmt:\n ");
5711 print_gimple_stmt (dump_file, stmt, 0);
5713 gimple_assign_set_rhs_from_tree (&gsi, val);
5714 update_stmt (stmt);
5716 if (dump_file && (dump_flags & TDF_DETAILS))
5718 fprintf (dump_file, "into:\n ");
5719 print_gimple_stmt (dump_file, stmt, 0);
5720 fprintf (dump_file, "\n");
5723 *m_something_changed = true;
5724 if (maybe_clean_eh_stmt (stmt))
5725 bitmap_set_bit (m_need_eh_cleanup, bb->index);
5727 return NULL;
5730 /* Return true if we have recorded VALUE and MASK about PARM.
5731 Set VALUE and MASk accordingly. */
5733 bool
5734 ipcp_get_parm_bits (tree parm, tree *value, widest_int *mask)
5736 cgraph_node *cnode = cgraph_node::get (current_function_decl);
5737 ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
5738 if (!ts || vec_safe_length (ts->bits) == 0)
5739 return false;
5741 int i = 0;
5742 for (tree p = DECL_ARGUMENTS (current_function_decl);
5743 p != parm; p = DECL_CHAIN (p))
5745 i++;
5746 /* Ignore static chain. */
5747 if (!p)
5748 return false;
5751 clone_info *cinfo = clone_info::get (cnode);
5752 if (cinfo && cinfo->param_adjustments)
5754 i = cinfo->param_adjustments->get_original_index (i);
5755 if (i < 0)
5756 return false;
5759 vec<ipa_bits *, va_gc> &bits = *ts->bits;
5760 if (!bits[i])
5761 return false;
5762 *mask = bits[i]->mask;
5763 *value = wide_int_to_tree (TREE_TYPE (parm), bits[i]->value);
5764 return true;
5768 /* Update bits info of formal parameters as described in
5769 ipcp_transformation. */
5771 static void
5772 ipcp_update_bits (struct cgraph_node *node)
5774 ipcp_transformation *ts = ipcp_get_transformation_summary (node);
5776 if (!ts || vec_safe_length (ts->bits) == 0)
5777 return;
5778 vec<ipa_bits *, va_gc> &bits = *ts->bits;
5779 unsigned count = bits.length ();
5780 if (!count)
5781 return;
5783 auto_vec<int, 16> new_indices;
5784 bool need_remapping = false;
5785 clone_info *cinfo = clone_info::get (node);
5786 if (cinfo && cinfo->param_adjustments)
5788 cinfo->param_adjustments->get_updated_indices (&new_indices);
5789 need_remapping = true;
5791 auto_vec <tree, 16> parm_decls;
5792 push_function_arg_decls (&parm_decls, node->decl);
5794 for (unsigned i = 0; i < count; ++i)
5796 tree parm;
5797 if (need_remapping)
5799 if (i >= new_indices.length ())
5800 continue;
5801 int idx = new_indices[i];
5802 if (idx < 0)
5803 continue;
5804 parm = parm_decls[idx];
5806 else
5807 parm = parm_decls[i];
5808 gcc_checking_assert (parm);
5811 if (!bits[i]
5812 || !(INTEGRAL_TYPE_P (TREE_TYPE (parm))
5813 || POINTER_TYPE_P (TREE_TYPE (parm)))
5814 || !is_gimple_reg (parm))
5815 continue;
5817 tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl), parm);
5818 if (!ddef)
5819 continue;
5821 if (dump_file)
5823 fprintf (dump_file, "Adjusting mask for param %u to ", i);
5824 print_hex (bits[i]->mask, dump_file);
5825 fprintf (dump_file, "\n");
5828 if (INTEGRAL_TYPE_P (TREE_TYPE (ddef)))
5830 unsigned prec = TYPE_PRECISION (TREE_TYPE (ddef));
5831 signop sgn = TYPE_SIGN (TREE_TYPE (ddef));
5833 wide_int nonzero_bits = wide_int::from (bits[i]->mask, prec, UNSIGNED)
5834 | wide_int::from (bits[i]->value, prec, sgn);
5835 set_nonzero_bits (ddef, nonzero_bits);
5837 else
5839 unsigned tem = bits[i]->mask.to_uhwi ();
5840 unsigned HOST_WIDE_INT bitpos = bits[i]->value.to_uhwi ();
5841 unsigned align = tem & -tem;
5842 unsigned misalign = bitpos & (align - 1);
5844 if (align > 1)
5846 if (dump_file)
5847 fprintf (dump_file, "Adjusting align: %u, misalign: %u\n", align, misalign);
5849 unsigned old_align, old_misalign;
5850 struct ptr_info_def *pi = get_ptr_info (ddef);
5851 bool old_known = get_ptr_info_alignment (pi, &old_align, &old_misalign);
5853 if (old_known
5854 && old_align > align)
5856 if (dump_file)
5858 fprintf (dump_file, "But alignment was already %u.\n", old_align);
5859 if ((old_misalign & (align - 1)) != misalign)
5860 fprintf (dump_file, "old_misalign (%u) and misalign (%u) mismatch\n",
5861 old_misalign, misalign);
5863 continue;
5866 if (old_known
5867 && ((misalign & (old_align - 1)) != old_misalign)
5868 && dump_file)
5869 fprintf (dump_file, "old_misalign (%u) and misalign (%u) mismatch\n",
5870 old_misalign, misalign);
5872 set_ptr_info_alignment (pi, align, misalign);
5878 bool
5879 ipa_vr::nonzero_p (tree expr_type) const
5881 if (type == VR_ANTI_RANGE && wi::eq_p (min, 0) && wi::eq_p (max, 0))
5882 return true;
5884 unsigned prec = TYPE_PRECISION (expr_type);
5885 return (type == VR_RANGE
5886 && TYPE_UNSIGNED (expr_type)
5887 && wi::eq_p (min, wi::one (prec))
5888 && wi::eq_p (max, wi::max_value (prec, TYPE_SIGN (expr_type))));
5891 /* Update value range of formal parameters as described in
5892 ipcp_transformation. */
5894 static void
5895 ipcp_update_vr (struct cgraph_node *node)
5897 ipcp_transformation *ts = ipcp_get_transformation_summary (node);
5898 if (!ts || vec_safe_length (ts->m_vr) == 0)
5899 return;
5900 const vec<ipa_vr, va_gc> &vr = *ts->m_vr;
5901 unsigned count = vr.length ();
5902 if (!count)
5903 return;
5905 auto_vec<int, 16> new_indices;
5906 bool need_remapping = false;
5907 clone_info *cinfo = clone_info::get (node);
5908 if (cinfo && cinfo->param_adjustments)
5910 cinfo->param_adjustments->get_updated_indices (&new_indices);
5911 need_remapping = true;
5913 auto_vec <tree, 16> parm_decls;
5914 push_function_arg_decls (&parm_decls, node->decl);
5916 for (unsigned i = 0; i < count; ++i)
5918 tree parm;
5919 int remapped_idx;
5920 if (need_remapping)
5922 if (i >= new_indices.length ())
5923 continue;
5924 remapped_idx = new_indices[i];
5925 if (remapped_idx < 0)
5926 continue;
5928 else
5929 remapped_idx = i;
5931 parm = parm_decls[remapped_idx];
5933 gcc_checking_assert (parm);
5934 tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl), parm);
5936 if (!ddef || !is_gimple_reg (parm))
5937 continue;
5939 if (vr[i].known
5940 && (vr[i].type == VR_RANGE || vr[i].type == VR_ANTI_RANGE))
5942 tree type = TREE_TYPE (ddef);
5943 unsigned prec = TYPE_PRECISION (type);
5944 if (INTEGRAL_TYPE_P (TREE_TYPE (ddef)))
5946 if (dump_file)
5948 fprintf (dump_file, "Setting value range of param %u "
5949 "(now %i) ", i, remapped_idx);
5950 fprintf (dump_file, "%s[",
5951 (vr[i].type == VR_ANTI_RANGE) ? "~" : "");
5952 print_decs (vr[i].min, dump_file);
5953 fprintf (dump_file, ", ");
5954 print_decs (vr[i].max, dump_file);
5955 fprintf (dump_file, "]\n");
5957 set_range_info (ddef, vr[i].type,
5958 wide_int_storage::from (vr[i].min, prec,
5959 TYPE_SIGN (type)),
5960 wide_int_storage::from (vr[i].max, prec,
5961 TYPE_SIGN (type)));
5963 else if (POINTER_TYPE_P (TREE_TYPE (ddef))
5964 && vr[i].nonzero_p (TREE_TYPE (ddef)))
5966 if (dump_file)
5967 fprintf (dump_file, "Setting nonnull for %u\n", i);
5968 set_ptr_nonnull (ddef);
5974 /* IPCP transformation phase doing propagation of aggregate values. */
5976 unsigned int
5977 ipcp_transform_function (struct cgraph_node *node)
5979 vec<ipa_param_descriptor, va_gc> *descriptors = NULL;
5980 struct ipa_func_body_info fbi;
5981 struct ipa_agg_replacement_value *aggval;
5982 int param_count;
5983 bool something_changed = false;
5985 gcc_checking_assert (cfun);
5986 gcc_checking_assert (current_function_decl);
5988 if (dump_file)
5989 fprintf (dump_file, "Modification phase of node %s\n",
5990 node->dump_name ());
5992 ipcp_update_bits (node);
5993 ipcp_update_vr (node);
5994 aggval = ipa_get_agg_replacements_for_node (node);
5995 if (!aggval)
5996 return 0;
5997 param_count = count_formal_params (node->decl);
5998 if (param_count == 0)
5999 return 0;
6000 adjust_agg_replacement_values (node, aggval);
6001 if (dump_file)
6002 ipa_dump_agg_replacement_values (dump_file, aggval);
6004 fbi.node = node;
6005 fbi.info = NULL;
6006 fbi.bb_infos = vNULL;
6007 fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
6008 fbi.param_count = param_count;
6009 fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps);
6011 vec_safe_grow_cleared (descriptors, param_count, true);
6012 ipa_populate_param_decls (node, *descriptors);
6013 calculate_dominance_info (CDI_DOMINATORS);
6014 ipcp_modif_dom_walker walker (&fbi, descriptors, aggval, &something_changed);
6015 walker.walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
6016 free_dominance_info (CDI_DOMINATORS);
6017 bool cfg_changed = walker.cleanup_eh ();
6019 int i;
6020 struct ipa_bb_info *bi;
6021 FOR_EACH_VEC_ELT (fbi.bb_infos, i, bi)
6022 free_ipa_bb_info (bi);
6023 fbi.bb_infos.release ();
6025 ipcp_transformation *s = ipcp_transformation_sum->get (node);
6026 s->agg_values = NULL;
6027 s->bits = NULL;
6028 s->m_vr = NULL;
6030 vec_free (descriptors);
6032 if (!something_changed)
6033 return 0;
6035 if (cfg_changed)
6036 delete_unreachable_blocks_update_callgraph (node, false);
6038 return TODO_update_ssa_only_virtuals;
6042 /* Return true if OTHER describes same agg value. */
6043 bool
6044 ipa_agg_value::equal_to (const ipa_agg_value &other)
6046 return offset == other.offset
6047 && operand_equal_p (value, other.value, 0);
6050 /* Destructor also removing individual aggregate values. */
6052 ipa_auto_call_arg_values::~ipa_auto_call_arg_values ()
6054 ipa_release_agg_values (m_known_aggs, false);
6059 #include "gt-ipa-prop.h"