2015-06-11 Paul Thomas <pault@gcc.gnu.org>
[official-gcc.git] / gcc / ipa-prop.c
blob9290bfb2e4b316146889178379c576bf11f8e8d5
1 /* Interprocedural analyses.
2 Copyright (C) 2005-2015 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 "input.h"
24 #include "alias.h"
25 #include "symtab.h"
26 #include "options.h"
27 #include "tree.h"
28 #include "fold-const.h"
29 #include "predict.h"
30 #include "tm.h"
31 #include "hard-reg-set.h"
32 #include "function.h"
33 #include "dominance.h"
34 #include "cfg.h"
35 #include "basic-block.h"
36 #include "tree-ssa-alias.h"
37 #include "internal-fn.h"
38 #include "gimple-fold.h"
39 #include "tree-eh.h"
40 #include "gimple-expr.h"
41 #include "is-a.h"
42 #include "gimple.h"
43 #include "rtl.h"
44 #include "flags.h"
45 #include "insn-config.h"
46 #include "expmed.h"
47 #include "dojump.h"
48 #include "explow.h"
49 #include "calls.h"
50 #include "emit-rtl.h"
51 #include "varasm.h"
52 #include "stmt.h"
53 #include "expr.h"
54 #include "stor-layout.h"
55 #include "print-tree.h"
56 #include "gimplify.h"
57 #include "gimple-iterator.h"
58 #include "gimplify-me.h"
59 #include "gimple-walk.h"
60 #include "langhooks.h"
61 #include "target.h"
62 #include "plugin-api.h"
63 #include "ipa-ref.h"
64 #include "cgraph.h"
65 #include "alloc-pool.h"
66 #include "symbol-summary.h"
67 #include "ipa-prop.h"
68 #include "bitmap.h"
69 #include "gimple-ssa.h"
70 #include "tree-cfg.h"
71 #include "tree-phinodes.h"
72 #include "ssa-iterators.h"
73 #include "tree-into-ssa.h"
74 #include "tree-dfa.h"
75 #include "tree-pass.h"
76 #include "tree-inline.h"
77 #include "ipa-inline.h"
78 #include "diagnostic.h"
79 #include "gimple-pretty-print.h"
80 #include "lto-streamer.h"
81 #include "data-streamer.h"
82 #include "tree-streamer.h"
83 #include "params.h"
84 #include "ipa-utils.h"
85 #include "stringpool.h"
86 #include "tree-ssanames.h"
87 #include "dbgcnt.h"
88 #include "domwalk.h"
89 #include "builtins.h"
91 /* Intermediate information that we get from alias analysis about a particular
92 parameter in a particular basic_block. When a parameter or the memory it
93 references is marked modified, we use that information in all dominatd
94 blocks without cosulting alias analysis oracle. */
96 struct param_aa_status
98 /* Set when this structure contains meaningful information. If not, the
99 structure describing a dominating BB should be used instead. */
100 bool valid;
102 /* Whether we have seen something which might have modified the data in
103 question. PARM is for the parameter itself, REF is for data it points to
104 but using the alias type of individual accesses and PT is the same thing
105 but for computing aggregate pass-through functions using a very inclusive
106 ao_ref. */
107 bool parm_modified, ref_modified, pt_modified;
110 /* Information related to a given BB that used only when looking at function
111 body. */
113 struct ipa_bb_info
115 /* Call graph edges going out of this BB. */
116 vec<cgraph_edge *> cg_edges;
117 /* Alias analysis statuses of each formal parameter at this bb. */
118 vec<param_aa_status> param_aa_statuses;
121 /* Structure with global information that is only used when looking at function
122 body. */
124 struct func_body_info
126 /* The node that is being analyzed. */
127 cgraph_node *node;
129 /* Its info. */
130 struct ipa_node_params *info;
132 /* Information about individual BBs. */
133 vec<ipa_bb_info> bb_infos;
135 /* Number of parameters. */
136 int param_count;
138 /* Number of statements already walked by when analyzing this function. */
139 unsigned int aa_walked;
142 /* Function summary where the parameter infos are actually stored. */
143 ipa_node_params_t *ipa_node_params_sum = NULL;
144 /* Vector of IPA-CP transformation data for each clone. */
145 vec<ipcp_transformation_summary, va_gc> *ipcp_transformations;
146 /* Vector where the parameter infos are actually stored. */
147 vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
149 /* Holders of ipa cgraph hooks: */
150 static struct cgraph_edge_hook_list *edge_removal_hook_holder;
151 static struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
152 static struct cgraph_node_hook_list *function_insertion_hook_holder;
154 /* Description of a reference to an IPA constant. */
155 struct ipa_cst_ref_desc
157 /* Edge that corresponds to the statement which took the reference. */
158 struct cgraph_edge *cs;
159 /* Linked list of duplicates created when call graph edges are cloned. */
160 struct ipa_cst_ref_desc *next_duplicate;
161 /* Number of references in IPA structures, IPA_UNDESCRIBED_USE if the value
162 if out of control. */
163 int refcount;
166 /* Allocation pool for reference descriptions. */
168 static pool_allocator<ipa_cst_ref_desc> ipa_refdesc_pool
169 ("IPA-PROP ref descriptions", 32);
171 /* Return true if DECL_FUNCTION_SPECIFIC_OPTIMIZATION of the decl associated
172 with NODE should prevent us from analyzing it for the purposes of IPA-CP. */
174 static bool
175 ipa_func_spec_opts_forbid_analysis_p (struct cgraph_node *node)
177 tree fs_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (node->decl);
179 if (!fs_opts)
180 return false;
181 return !opt_for_fn (node->decl, optimize) || !opt_for_fn (node->decl, flag_ipa_cp);
184 /* Return index of the formal whose tree is PTREE in function which corresponds
185 to INFO. */
187 static int
188 ipa_get_param_decl_index_1 (vec<ipa_param_descriptor> descriptors, tree ptree)
190 int i, count;
192 count = descriptors.length ();
193 for (i = 0; i < count; i++)
194 if (descriptors[i].decl == ptree)
195 return i;
197 return -1;
200 /* Return index of the formal whose tree is PTREE in function which corresponds
201 to INFO. */
204 ipa_get_param_decl_index (struct ipa_node_params *info, tree ptree)
206 return ipa_get_param_decl_index_1 (info->descriptors, ptree);
209 /* Populate the param_decl field in parameter DESCRIPTORS that correspond to
210 NODE. */
212 static void
213 ipa_populate_param_decls (struct cgraph_node *node,
214 vec<ipa_param_descriptor> &descriptors)
216 tree fndecl;
217 tree fnargs;
218 tree parm;
219 int param_num;
221 fndecl = node->decl;
222 gcc_assert (gimple_has_body_p (fndecl));
223 fnargs = DECL_ARGUMENTS (fndecl);
224 param_num = 0;
225 for (parm = fnargs; parm; parm = DECL_CHAIN (parm))
227 descriptors[param_num].decl = parm;
228 descriptors[param_num].move_cost = estimate_move_cost (TREE_TYPE (parm),
229 true);
230 param_num++;
234 /* Return how many formal parameters FNDECL has. */
237 count_formal_params (tree fndecl)
239 tree parm;
240 int count = 0;
241 gcc_assert (gimple_has_body_p (fndecl));
243 for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
244 count++;
246 return count;
249 /* Return the declaration of Ith formal parameter of the function corresponding
250 to INFO. Note there is no setter function as this array is built just once
251 using ipa_initialize_node_params. */
253 void
254 ipa_dump_param (FILE *file, struct ipa_node_params *info, int i)
256 fprintf (file, "param #%i", i);
257 if (info->descriptors[i].decl)
259 fprintf (file, " ");
260 print_generic_expr (file, info->descriptors[i].decl, 0);
264 /* Initialize the ipa_node_params structure associated with NODE
265 to hold PARAM_COUNT parameters. */
267 void
268 ipa_alloc_node_params (struct cgraph_node *node, int param_count)
270 struct ipa_node_params *info = IPA_NODE_REF (node);
272 if (!info->descriptors.exists () && param_count)
273 info->descriptors.safe_grow_cleared (param_count);
276 /* Initialize the ipa_node_params structure associated with NODE by counting
277 the function parameters, creating the descriptors and populating their
278 param_decls. */
280 void
281 ipa_initialize_node_params (struct cgraph_node *node)
283 struct ipa_node_params *info = IPA_NODE_REF (node);
285 if (!info->descriptors.exists ())
287 ipa_alloc_node_params (node, count_formal_params (node->decl));
288 ipa_populate_param_decls (node, info->descriptors);
292 /* Print the jump functions associated with call graph edge CS to file F. */
294 static void
295 ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
297 int i, count;
299 count = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
300 for (i = 0; i < count; i++)
302 struct ipa_jump_func *jump_func;
303 enum jump_func_type type;
305 jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
306 type = jump_func->type;
308 fprintf (f, " param %d: ", i);
309 if (type == IPA_JF_UNKNOWN)
310 fprintf (f, "UNKNOWN\n");
311 else if (type == IPA_JF_CONST)
313 tree val = jump_func->value.constant.value;
314 fprintf (f, "CONST: ");
315 print_generic_expr (f, val, 0);
316 if (TREE_CODE (val) == ADDR_EXPR
317 && TREE_CODE (TREE_OPERAND (val, 0)) == CONST_DECL)
319 fprintf (f, " -> ");
320 print_generic_expr (f, DECL_INITIAL (TREE_OPERAND (val, 0)),
323 fprintf (f, "\n");
325 else if (type == IPA_JF_PASS_THROUGH)
327 fprintf (f, "PASS THROUGH: ");
328 fprintf (f, "%d, op %s",
329 jump_func->value.pass_through.formal_id,
330 get_tree_code_name(jump_func->value.pass_through.operation));
331 if (jump_func->value.pass_through.operation != NOP_EXPR)
333 fprintf (f, " ");
334 print_generic_expr (f,
335 jump_func->value.pass_through.operand, 0);
337 if (jump_func->value.pass_through.agg_preserved)
338 fprintf (f, ", agg_preserved");
339 fprintf (f, "\n");
341 else if (type == IPA_JF_ANCESTOR)
343 fprintf (f, "ANCESTOR: ");
344 fprintf (f, "%d, offset " HOST_WIDE_INT_PRINT_DEC,
345 jump_func->value.ancestor.formal_id,
346 jump_func->value.ancestor.offset);
347 if (jump_func->value.ancestor.agg_preserved)
348 fprintf (f, ", agg_preserved");
349 fprintf (f, "\n");
352 if (jump_func->agg.items)
354 struct ipa_agg_jf_item *item;
355 int j;
357 fprintf (f, " Aggregate passed by %s:\n",
358 jump_func->agg.by_ref ? "reference" : "value");
359 FOR_EACH_VEC_SAFE_ELT (jump_func->agg.items, j, item)
361 fprintf (f, " offset: " HOST_WIDE_INT_PRINT_DEC ", ",
362 item->offset);
363 if (TYPE_P (item->value))
364 fprintf (f, "clobber of " HOST_WIDE_INT_PRINT_DEC " bits",
365 tree_to_uhwi (TYPE_SIZE (item->value)));
366 else
368 fprintf (f, "cst: ");
369 print_generic_expr (f, item->value, 0);
371 fprintf (f, "\n");
375 struct ipa_polymorphic_call_context *ctx
376 = ipa_get_ith_polymorhic_call_context (IPA_EDGE_REF (cs), i);
377 if (ctx && !ctx->useless_p ())
379 fprintf (f, " Context: ");
380 ctx->dump (dump_file);
383 if (jump_func->alignment.known)
385 fprintf (f, " Alignment: %u, misalignment: %u\n",
386 jump_func->alignment.align,
387 jump_func->alignment.misalign);
389 else
390 fprintf (f, " Unknown alignment\n");
395 /* Print the jump functions of all arguments on all call graph edges going from
396 NODE to file F. */
398 void
399 ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
401 struct cgraph_edge *cs;
403 fprintf (f, " Jump functions of caller %s/%i:\n", node->name (),
404 node->order);
405 for (cs = node->callees; cs; cs = cs->next_callee)
407 if (!ipa_edge_args_info_available_for_edge_p (cs))
408 continue;
410 fprintf (f, " callsite %s/%i -> %s/%i : \n",
411 xstrdup_for_dump (node->name ()), node->order,
412 xstrdup_for_dump (cs->callee->name ()),
413 cs->callee->order);
414 ipa_print_node_jump_functions_for_edge (f, cs);
417 for (cs = node->indirect_calls; cs; cs = cs->next_callee)
419 struct cgraph_indirect_call_info *ii;
420 if (!ipa_edge_args_info_available_for_edge_p (cs))
421 continue;
423 ii = cs->indirect_info;
424 if (ii->agg_contents)
425 fprintf (f, " indirect %s callsite, calling param %i, "
426 "offset " HOST_WIDE_INT_PRINT_DEC ", %s",
427 ii->member_ptr ? "member ptr" : "aggregate",
428 ii->param_index, ii->offset,
429 ii->by_ref ? "by reference" : "by_value");
430 else
431 fprintf (f, " indirect %s callsite, calling param %i, "
432 "offset " HOST_WIDE_INT_PRINT_DEC,
433 ii->polymorphic ? "polymorphic" : "simple", ii->param_index,
434 ii->offset);
436 if (cs->call_stmt)
438 fprintf (f, ", for stmt ");
439 print_gimple_stmt (f, cs->call_stmt, 0, TDF_SLIM);
441 else
442 fprintf (f, "\n");
443 if (ii->polymorphic)
444 ii->context.dump (f);
445 ipa_print_node_jump_functions_for_edge (f, cs);
449 /* Print ipa_jump_func data structures of all nodes in the call graph to F. */
451 void
452 ipa_print_all_jump_functions (FILE *f)
454 struct cgraph_node *node;
456 fprintf (f, "\nJump functions:\n");
457 FOR_EACH_FUNCTION (node)
459 ipa_print_node_jump_functions (f, node);
463 /* Set jfunc to be a know-really nothing jump function. */
465 static void
466 ipa_set_jf_unknown (struct ipa_jump_func *jfunc)
468 jfunc->type = IPA_JF_UNKNOWN;
469 jfunc->alignment.known = false;
472 /* Set JFUNC to be a copy of another jmp (to be used by jump function
473 combination code). The two functions will share their rdesc. */
475 static void
476 ipa_set_jf_cst_copy (struct ipa_jump_func *dst,
477 struct ipa_jump_func *src)
480 gcc_checking_assert (src->type == IPA_JF_CONST);
481 dst->type = IPA_JF_CONST;
482 dst->value.constant = src->value.constant;
485 /* Set JFUNC to be a constant jmp function. */
487 static void
488 ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
489 struct cgraph_edge *cs)
491 constant = unshare_expr (constant);
492 if (constant && EXPR_P (constant))
493 SET_EXPR_LOCATION (constant, UNKNOWN_LOCATION);
494 jfunc->type = IPA_JF_CONST;
495 jfunc->value.constant.value = unshare_expr_without_location (constant);
497 if (TREE_CODE (constant) == ADDR_EXPR
498 && TREE_CODE (TREE_OPERAND (constant, 0)) == FUNCTION_DECL)
500 struct ipa_cst_ref_desc *rdesc;
502 rdesc = ipa_refdesc_pool.allocate ();
503 rdesc->cs = cs;
504 rdesc->next_duplicate = NULL;
505 rdesc->refcount = 1;
506 jfunc->value.constant.rdesc = rdesc;
508 else
509 jfunc->value.constant.rdesc = NULL;
512 /* Set JFUNC to be a simple pass-through jump function. */
513 static void
514 ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
515 bool agg_preserved)
517 jfunc->type = IPA_JF_PASS_THROUGH;
518 jfunc->value.pass_through.operand = NULL_TREE;
519 jfunc->value.pass_through.formal_id = formal_id;
520 jfunc->value.pass_through.operation = NOP_EXPR;
521 jfunc->value.pass_through.agg_preserved = agg_preserved;
524 /* Set JFUNC to be an arithmetic pass through jump function. */
526 static void
527 ipa_set_jf_arith_pass_through (struct ipa_jump_func *jfunc, int formal_id,
528 tree operand, enum tree_code operation)
530 jfunc->type = IPA_JF_PASS_THROUGH;
531 jfunc->value.pass_through.operand = unshare_expr_without_location (operand);
532 jfunc->value.pass_through.formal_id = formal_id;
533 jfunc->value.pass_through.operation = operation;
534 jfunc->value.pass_through.agg_preserved = false;
537 /* Set JFUNC to be an ancestor jump function. */
539 static void
540 ipa_set_ancestor_jf (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
541 int formal_id, bool agg_preserved)
543 jfunc->type = IPA_JF_ANCESTOR;
544 jfunc->value.ancestor.formal_id = formal_id;
545 jfunc->value.ancestor.offset = offset;
546 jfunc->value.ancestor.agg_preserved = agg_preserved;
549 /* Get IPA BB information about the given BB. FBI is the context of analyzis
550 of this function body. */
552 static struct ipa_bb_info *
553 ipa_get_bb_info (struct func_body_info *fbi, basic_block bb)
555 gcc_checking_assert (fbi);
556 return &fbi->bb_infos[bb->index];
559 /* Structure to be passed in between detect_type_change and
560 check_stmt_for_type_change. */
562 struct prop_type_change_info
564 /* Offset into the object where there is the virtual method pointer we are
565 looking for. */
566 HOST_WIDE_INT offset;
567 /* The declaration or SSA_NAME pointer of the base that we are checking for
568 type change. */
569 tree object;
570 /* Set to true if dynamic type change has been detected. */
571 bool type_maybe_changed;
574 /* Return true if STMT can modify a virtual method table pointer.
576 This function makes special assumptions about both constructors and
577 destructors which are all the functions that are allowed to alter the VMT
578 pointers. It assumes that destructors begin with assignment into all VMT
579 pointers and that constructors essentially look in the following way:
581 1) The very first thing they do is that they call constructors of ancestor
582 sub-objects that have them.
584 2) Then VMT pointers of this and all its ancestors is set to new values
585 corresponding to the type corresponding to the constructor.
587 3) Only afterwards, other stuff such as constructor of member sub-objects
588 and the code written by the user is run. Only this may include calling
589 virtual functions, directly or indirectly.
591 There is no way to call a constructor of an ancestor sub-object in any
592 other way.
594 This means that we do not have to care whether constructors get the correct
595 type information because they will always change it (in fact, if we define
596 the type to be given by the VMT pointer, it is undefined).
598 The most important fact to derive from the above is that if, for some
599 statement in the section 3, we try to detect whether the dynamic type has
600 changed, we can safely ignore all calls as we examine the function body
601 backwards until we reach statements in section 2 because these calls cannot
602 be ancestor constructors or destructors (if the input is not bogus) and so
603 do not change the dynamic type (this holds true only for automatically
604 allocated objects but at the moment we devirtualize only these). We then
605 must detect that statements in section 2 change the dynamic type and can try
606 to derive the new type. That is enough and we can stop, we will never see
607 the calls into constructors of sub-objects in this code. Therefore we can
608 safely ignore all call statements that we traverse.
611 static bool
612 stmt_may_be_vtbl_ptr_store (gimple stmt)
614 if (is_gimple_call (stmt))
615 return false;
616 if (gimple_clobber_p (stmt))
617 return false;
618 else if (is_gimple_assign (stmt))
620 tree lhs = gimple_assign_lhs (stmt);
622 if (!AGGREGATE_TYPE_P (TREE_TYPE (lhs)))
624 if (flag_strict_aliasing
625 && !POINTER_TYPE_P (TREE_TYPE (lhs)))
626 return false;
628 if (TREE_CODE (lhs) == COMPONENT_REF
629 && !DECL_VIRTUAL_P (TREE_OPERAND (lhs, 1)))
630 return false;
631 /* In the future we might want to use get_base_ref_and_offset to find
632 if there is a field corresponding to the offset and if so, proceed
633 almost like if it was a component ref. */
636 return true;
639 /* Callback of walk_aliased_vdefs and a helper function for detect_type_change
640 to check whether a particular statement may modify the virtual table
641 pointerIt stores its result into DATA, which points to a
642 prop_type_change_info structure. */
644 static bool
645 check_stmt_for_type_change (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
647 gimple stmt = SSA_NAME_DEF_STMT (vdef);
648 struct prop_type_change_info *tci = (struct prop_type_change_info *) data;
650 if (stmt_may_be_vtbl_ptr_store (stmt))
652 tci->type_maybe_changed = true;
653 return true;
655 else
656 return false;
659 /* See if ARG is PARAM_DECl describing instance passed by pointer
660 or reference in FUNCTION. Return false if the dynamic type may change
661 in between beggining of the function until CALL is invoked.
663 Generally functions are not allowed to change type of such instances,
664 but they call destructors. We assume that methods can not destroy the THIS
665 pointer. Also as a special cases, constructor and destructors may change
666 type of the THIS pointer. */
668 static bool
669 param_type_may_change_p (tree function, tree arg, gimple call)
671 /* Pure functions can not do any changes on the dynamic type;
672 that require writting to memory. */
673 if (flags_from_decl_or_type (function) & (ECF_PURE | ECF_CONST))
674 return false;
675 /* We need to check if we are within inlined consturctor
676 or destructor (ideally we would have way to check that the
677 inline cdtor is actually working on ARG, but we don't have
678 easy tie on this, so punt on all non-pure cdtors.
679 We may also record the types of cdtors and once we know type
680 of the instance match them.
682 Also code unification optimizations may merge calls from
683 different blocks making return values unreliable. So
684 do nothing during late optimization. */
685 if (DECL_STRUCT_FUNCTION (function)->after_inlining)
686 return true;
687 if (TREE_CODE (arg) == SSA_NAME
688 && SSA_NAME_IS_DEFAULT_DEF (arg)
689 && TREE_CODE (SSA_NAME_VAR (arg)) == PARM_DECL)
691 /* Normal (non-THIS) argument. */
692 if ((SSA_NAME_VAR (arg) != DECL_ARGUMENTS (function)
693 || TREE_CODE (TREE_TYPE (function)) != METHOD_TYPE)
694 /* THIS pointer of an method - here we we want to watch constructors
695 and destructors as those definitely may change the dynamic
696 type. */
697 || (TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE
698 && !DECL_CXX_CONSTRUCTOR_P (function)
699 && !DECL_CXX_DESTRUCTOR_P (function)
700 && (SSA_NAME_VAR (arg) == DECL_ARGUMENTS (function))))
702 /* Walk the inline stack and watch out for ctors/dtors. */
703 for (tree block = gimple_block (call); block && TREE_CODE (block) == BLOCK;
704 block = BLOCK_SUPERCONTEXT (block))
705 if (inlined_polymorphic_ctor_dtor_block_p (block, false))
706 return true;
707 return false;
710 return true;
713 /* Detect whether the dynamic type of ARG of COMP_TYPE has changed (before
714 callsite CALL) by looking for assignments to its virtual table pointer. If
715 it is, return true and fill in the jump function JFUNC with relevant type
716 information or set it to unknown. ARG is the object itself (not a pointer
717 to it, unless dereferenced). BASE is the base of the memory access as
718 returned by get_ref_base_and_extent, as is the offset.
720 This is helper function for detect_type_change and detect_type_change_ssa
721 that does the heavy work which is usually unnecesary. */
723 static bool
724 detect_type_change_from_memory_writes (tree arg, tree base, tree comp_type,
725 gcall *call, struct ipa_jump_func *jfunc,
726 HOST_WIDE_INT offset)
728 struct prop_type_change_info tci;
729 ao_ref ao;
730 bool entry_reached = false;
732 gcc_checking_assert (DECL_P (arg)
733 || TREE_CODE (arg) == MEM_REF
734 || handled_component_p (arg));
736 comp_type = TYPE_MAIN_VARIANT (comp_type);
738 /* Const calls cannot call virtual methods through VMT and so type changes do
739 not matter. */
740 if (!flag_devirtualize || !gimple_vuse (call)
741 /* Be sure expected_type is polymorphic. */
742 || !comp_type
743 || TREE_CODE (comp_type) != RECORD_TYPE
744 || !TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type))
745 || !BINFO_VTABLE (TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type))))
746 return true;
748 ao_ref_init (&ao, arg);
749 ao.base = base;
750 ao.offset = offset;
751 ao.size = POINTER_SIZE;
752 ao.max_size = ao.size;
754 tci.offset = offset;
755 tci.object = get_base_address (arg);
756 tci.type_maybe_changed = false;
758 walk_aliased_vdefs (&ao, gimple_vuse (call), check_stmt_for_type_change,
759 &tci, NULL, &entry_reached);
760 if (!tci.type_maybe_changed)
761 return false;
763 ipa_set_jf_unknown (jfunc);
764 return true;
767 /* Detect whether the dynamic type of ARG of COMP_TYPE may have changed.
768 If it is, return true and fill in the jump function JFUNC with relevant type
769 information or set it to unknown. ARG is the object itself (not a pointer
770 to it, unless dereferenced). BASE is the base of the memory access as
771 returned by get_ref_base_and_extent, as is the offset. */
773 static bool
774 detect_type_change (tree arg, tree base, tree comp_type, gcall *call,
775 struct ipa_jump_func *jfunc, HOST_WIDE_INT offset)
777 if (!flag_devirtualize)
778 return false;
780 if (TREE_CODE (base) == MEM_REF
781 && !param_type_may_change_p (current_function_decl,
782 TREE_OPERAND (base, 0),
783 call))
784 return false;
785 return detect_type_change_from_memory_writes (arg, base, comp_type,
786 call, jfunc, offset);
789 /* Like detect_type_change but ARG is supposed to be a non-dereferenced pointer
790 SSA name (its dereference will become the base and the offset is assumed to
791 be zero). */
793 static bool
794 detect_type_change_ssa (tree arg, tree comp_type,
795 gcall *call, struct ipa_jump_func *jfunc)
797 gcc_checking_assert (TREE_CODE (arg) == SSA_NAME);
798 if (!flag_devirtualize
799 || !POINTER_TYPE_P (TREE_TYPE (arg)))
800 return false;
802 if (!param_type_may_change_p (current_function_decl, arg, call))
803 return false;
805 arg = build2 (MEM_REF, ptr_type_node, arg,
806 build_int_cst (ptr_type_node, 0));
808 return detect_type_change_from_memory_writes (arg, arg, comp_type,
809 call, jfunc, 0);
812 /* Callback of walk_aliased_vdefs. Flags that it has been invoked to the
813 boolean variable pointed to by DATA. */
815 static bool
816 mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
817 void *data)
819 bool *b = (bool *) data;
820 *b = true;
821 return true;
824 /* Return true if we have already walked so many statements in AA that we
825 should really just start giving up. */
827 static bool
828 aa_overwalked (struct func_body_info *fbi)
830 gcc_checking_assert (fbi);
831 return fbi->aa_walked > (unsigned) PARAM_VALUE (PARAM_IPA_MAX_AA_STEPS);
834 /* Find the nearest valid aa status for parameter specified by INDEX that
835 dominates BB. */
837 static struct param_aa_status *
838 find_dominating_aa_status (struct func_body_info *fbi, basic_block bb,
839 int index)
841 while (true)
843 bb = get_immediate_dominator (CDI_DOMINATORS, bb);
844 if (!bb)
845 return NULL;
846 struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
847 if (!bi->param_aa_statuses.is_empty ()
848 && bi->param_aa_statuses[index].valid)
849 return &bi->param_aa_statuses[index];
853 /* Get AA status structure for the given BB and parameter with INDEX. Allocate
854 structures and/or intialize the result with a dominating description as
855 necessary. */
857 static struct param_aa_status *
858 parm_bb_aa_status_for_bb (struct func_body_info *fbi, basic_block bb,
859 int index)
861 gcc_checking_assert (fbi);
862 struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
863 if (bi->param_aa_statuses.is_empty ())
864 bi->param_aa_statuses.safe_grow_cleared (fbi->param_count);
865 struct param_aa_status *paa = &bi->param_aa_statuses[index];
866 if (!paa->valid)
868 gcc_checking_assert (!paa->parm_modified
869 && !paa->ref_modified
870 && !paa->pt_modified);
871 struct param_aa_status *dom_paa;
872 dom_paa = find_dominating_aa_status (fbi, bb, index);
873 if (dom_paa)
874 *paa = *dom_paa;
875 else
876 paa->valid = true;
879 return paa;
882 /* Return true if a load from a formal parameter PARM_LOAD is known to retrieve
883 a value known not to be modified in this function before reaching the
884 statement STMT. FBI holds information about the function we have so far
885 gathered but do not survive the summary building stage. */
887 static bool
888 parm_preserved_before_stmt_p (struct func_body_info *fbi, int index,
889 gimple stmt, tree parm_load)
891 struct param_aa_status *paa;
892 bool modified = false;
893 ao_ref refd;
895 /* FIXME: FBI can be NULL if we are being called from outside
896 ipa_node_analysis or ipcp_transform_function, which currently happens
897 during inlining analysis. It would be great to extend fbi's lifetime and
898 always have it. Currently, we are just not afraid of too much walking in
899 that case. */
900 if (fbi)
902 if (aa_overwalked (fbi))
903 return false;
904 paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (stmt), index);
905 if (paa->parm_modified)
906 return false;
908 else
909 paa = NULL;
911 gcc_checking_assert (gimple_vuse (stmt) != NULL_TREE);
912 ao_ref_init (&refd, parm_load);
913 int walked = walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified,
914 &modified, NULL);
915 if (fbi)
916 fbi->aa_walked += walked;
917 if (paa && modified)
918 paa->parm_modified = true;
919 return !modified;
922 /* If STMT is an assignment that loads a value from an parameter declaration,
923 return the index of the parameter in ipa_node_params which has not been
924 modified. Otherwise return -1. */
926 static int
927 load_from_unmodified_param (struct func_body_info *fbi,
928 vec<ipa_param_descriptor> descriptors,
929 gimple stmt)
931 int index;
932 tree op1;
934 if (!gimple_assign_single_p (stmt))
935 return -1;
937 op1 = gimple_assign_rhs1 (stmt);
938 if (TREE_CODE (op1) != PARM_DECL)
939 return -1;
941 index = ipa_get_param_decl_index_1 (descriptors, op1);
942 if (index < 0
943 || !parm_preserved_before_stmt_p (fbi, index, stmt, op1))
944 return -1;
946 return index;
949 /* Return true if memory reference REF (which must be a load through parameter
950 with INDEX) loads data that are known to be unmodified in this function
951 before reaching statement STMT. */
953 static bool
954 parm_ref_data_preserved_p (struct func_body_info *fbi,
955 int index, gimple stmt, tree ref)
957 struct param_aa_status *paa;
958 bool modified = false;
959 ao_ref refd;
961 /* FIXME: FBI can be NULL if we are being called from outside
962 ipa_node_analysis or ipcp_transform_function, which currently happens
963 during inlining analysis. It would be great to extend fbi's lifetime and
964 always have it. Currently, we are just not afraid of too much walking in
965 that case. */
966 if (fbi)
968 if (aa_overwalked (fbi))
969 return false;
970 paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (stmt), index);
971 if (paa->ref_modified)
972 return false;
974 else
975 paa = NULL;
977 gcc_checking_assert (gimple_vuse (stmt));
978 ao_ref_init (&refd, ref);
979 int walked = walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified,
980 &modified, NULL);
981 if (fbi)
982 fbi->aa_walked += walked;
983 if (paa && modified)
984 paa->ref_modified = true;
985 return !modified;
988 /* Return true if the data pointed to by PARM (which is a parameter with INDEX)
989 is known to be unmodified in this function before reaching call statement
990 CALL into which it is passed. FBI describes the function body. */
992 static bool
993 parm_ref_data_pass_through_p (struct func_body_info *fbi, int index,
994 gimple call, tree parm)
996 bool modified = false;
997 ao_ref refd;
999 /* It's unnecessary to calculate anything about memory contnets for a const
1000 function because it is not goin to use it. But do not cache the result
1001 either. Also, no such calculations for non-pointers. */
1002 if (!gimple_vuse (call)
1003 || !POINTER_TYPE_P (TREE_TYPE (parm))
1004 || aa_overwalked (fbi))
1005 return false;
1007 struct param_aa_status *paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (call),
1008 index);
1009 if (paa->pt_modified)
1010 return false;
1012 ao_ref_init_from_ptr_and_size (&refd, parm, NULL_TREE);
1013 int walked = walk_aliased_vdefs (&refd, gimple_vuse (call), mark_modified,
1014 &modified, NULL);
1015 fbi->aa_walked += walked;
1016 if (modified)
1017 paa->pt_modified = true;
1018 return !modified;
1021 /* Return true if we can prove that OP is a memory reference loading unmodified
1022 data from an aggregate passed as a parameter and if the aggregate is passed
1023 by reference, that the alias type of the load corresponds to the type of the
1024 formal parameter (so that we can rely on this type for TBAA in callers).
1025 INFO and PARMS_AINFO describe parameters of the current function (but the
1026 latter can be NULL), STMT is the load statement. If function returns true,
1027 *INDEX_P, *OFFSET_P and *BY_REF is filled with the parameter index, offset
1028 within the aggregate and whether it is a load from a value passed by
1029 reference respectively. */
1031 static bool
1032 ipa_load_from_parm_agg_1 (struct func_body_info *fbi,
1033 vec<ipa_param_descriptor> descriptors,
1034 gimple stmt, tree op, int *index_p,
1035 HOST_WIDE_INT *offset_p, HOST_WIDE_INT *size_p,
1036 bool *by_ref_p)
1038 int index;
1039 HOST_WIDE_INT size, max_size;
1040 tree base = get_ref_base_and_extent (op, offset_p, &size, &max_size);
1042 if (max_size == -1 || max_size != size || *offset_p < 0)
1043 return false;
1045 if (DECL_P (base))
1047 int index = ipa_get_param_decl_index_1 (descriptors, base);
1048 if (index >= 0
1049 && parm_preserved_before_stmt_p (fbi, index, stmt, op))
1051 *index_p = index;
1052 *by_ref_p = false;
1053 if (size_p)
1054 *size_p = size;
1055 return true;
1057 return false;
1060 if (TREE_CODE (base) != MEM_REF
1061 || TREE_CODE (TREE_OPERAND (base, 0)) != SSA_NAME
1062 || !integer_zerop (TREE_OPERAND (base, 1)))
1063 return false;
1065 if (SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (base, 0)))
1067 tree parm = SSA_NAME_VAR (TREE_OPERAND (base, 0));
1068 index = ipa_get_param_decl_index_1 (descriptors, parm);
1070 else
1072 /* This branch catches situations where a pointer parameter is not a
1073 gimple register, for example:
1075 void hip7(S*) (struct S * p)
1077 void (*<T2e4>) (struct S *) D.1867;
1078 struct S * p.1;
1080 <bb 2>:
1081 p.1_1 = p;
1082 D.1867_2 = p.1_1->f;
1083 D.1867_2 ();
1084 gdp = &p;
1087 gimple def = SSA_NAME_DEF_STMT (TREE_OPERAND (base, 0));
1088 index = load_from_unmodified_param (fbi, descriptors, def);
1091 if (index >= 0
1092 && parm_ref_data_preserved_p (fbi, index, stmt, op))
1094 *index_p = index;
1095 *by_ref_p = true;
1096 if (size_p)
1097 *size_p = size;
1098 return true;
1100 return false;
1103 /* Just like the previous function, just without the param_analysis_info
1104 pointer, for users outside of this file. */
1106 bool
1107 ipa_load_from_parm_agg (struct ipa_node_params *info, gimple stmt,
1108 tree op, int *index_p, HOST_WIDE_INT *offset_p,
1109 bool *by_ref_p)
1111 return ipa_load_from_parm_agg_1 (NULL, info->descriptors, stmt, op, index_p,
1112 offset_p, NULL, by_ref_p);
1115 /* Given that an actual argument is an SSA_NAME (given in NAME) and is a result
1116 of an assignment statement STMT, try to determine whether we are actually
1117 handling any of the following cases and construct an appropriate jump
1118 function into JFUNC if so:
1120 1) The passed value is loaded from a formal parameter which is not a gimple
1121 register (most probably because it is addressable, the value has to be
1122 scalar) and we can guarantee the value has not changed. This case can
1123 therefore be described by a simple pass-through jump function. For example:
1125 foo (int a)
1127 int a.0;
1129 a.0_2 = a;
1130 bar (a.0_2);
1132 2) The passed value can be described by a simple arithmetic pass-through
1133 jump function. E.g.
1135 foo (int a)
1137 int D.2064;
1139 D.2064_4 = a.1(D) + 4;
1140 bar (D.2064_4);
1142 This case can also occur in combination of the previous one, e.g.:
1144 foo (int a, int z)
1146 int a.0;
1147 int D.2064;
1149 a.0_3 = a;
1150 D.2064_4 = a.0_3 + 4;
1151 foo (D.2064_4);
1153 3) The passed value is an address of an object within another one (which
1154 also passed by reference). Such situations are described by an ancestor
1155 jump function and describe situations such as:
1157 B::foo() (struct B * const this)
1159 struct A * D.1845;
1161 D.1845_2 = &this_1(D)->D.1748;
1162 A::bar (D.1845_2);
1164 INFO is the structure describing individual parameters access different
1165 stages of IPA optimizations. PARMS_AINFO contains the information that is
1166 only needed for intraprocedural analysis. */
1168 static void
1169 compute_complex_assign_jump_func (struct func_body_info *fbi,
1170 struct ipa_node_params *info,
1171 struct ipa_jump_func *jfunc,
1172 gcall *call, gimple stmt, tree name,
1173 tree param_type)
1175 HOST_WIDE_INT offset, size, max_size;
1176 tree op1, tc_ssa, base, ssa;
1177 int index;
1179 op1 = gimple_assign_rhs1 (stmt);
1181 if (TREE_CODE (op1) == SSA_NAME)
1183 if (SSA_NAME_IS_DEFAULT_DEF (op1))
1184 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (op1));
1185 else
1186 index = load_from_unmodified_param (fbi, info->descriptors,
1187 SSA_NAME_DEF_STMT (op1));
1188 tc_ssa = op1;
1190 else
1192 index = load_from_unmodified_param (fbi, info->descriptors, stmt);
1193 tc_ssa = gimple_assign_lhs (stmt);
1196 if (index >= 0)
1198 tree op2 = gimple_assign_rhs2 (stmt);
1200 if (op2)
1202 if (!is_gimple_ip_invariant (op2)
1203 || (TREE_CODE_CLASS (gimple_expr_code (stmt)) != tcc_comparison
1204 && !useless_type_conversion_p (TREE_TYPE (name),
1205 TREE_TYPE (op1))))
1206 return;
1208 ipa_set_jf_arith_pass_through (jfunc, index, op2,
1209 gimple_assign_rhs_code (stmt));
1211 else if (gimple_assign_single_p (stmt))
1213 bool agg_p = parm_ref_data_pass_through_p (fbi, index, call, tc_ssa);
1214 ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
1216 return;
1219 if (TREE_CODE (op1) != ADDR_EXPR)
1220 return;
1221 op1 = TREE_OPERAND (op1, 0);
1222 if (TREE_CODE (TREE_TYPE (op1)) != RECORD_TYPE)
1223 return;
1224 base = get_ref_base_and_extent (op1, &offset, &size, &max_size);
1225 if (TREE_CODE (base) != MEM_REF
1226 /* If this is a varying address, punt. */
1227 || max_size == -1
1228 || max_size != size)
1229 return;
1230 offset += mem_ref_offset (base).to_short_addr () * BITS_PER_UNIT;
1231 ssa = TREE_OPERAND (base, 0);
1232 if (TREE_CODE (ssa) != SSA_NAME
1233 || !SSA_NAME_IS_DEFAULT_DEF (ssa)
1234 || offset < 0)
1235 return;
1237 /* Dynamic types are changed in constructors and destructors. */
1238 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (ssa));
1239 if (index >= 0 && param_type && POINTER_TYPE_P (param_type))
1240 ipa_set_ancestor_jf (jfunc, offset, index,
1241 parm_ref_data_pass_through_p (fbi, index, call, ssa));
1244 /* Extract the base, offset and MEM_REF expression from a statement ASSIGN if
1245 it looks like:
1247 iftmp.1_3 = &obj_2(D)->D.1762;
1249 The base of the MEM_REF must be a default definition SSA NAME of a
1250 parameter. Return NULL_TREE if it looks otherwise. If case of success, the
1251 whole MEM_REF expression is returned and the offset calculated from any
1252 handled components and the MEM_REF itself is stored into *OFFSET. The whole
1253 RHS stripped off the ADDR_EXPR is stored into *OBJ_P. */
1255 static tree
1256 get_ancestor_addr_info (gimple assign, tree *obj_p, HOST_WIDE_INT *offset)
1258 HOST_WIDE_INT size, max_size;
1259 tree expr, parm, obj;
1261 if (!gimple_assign_single_p (assign))
1262 return NULL_TREE;
1263 expr = gimple_assign_rhs1 (assign);
1265 if (TREE_CODE (expr) != ADDR_EXPR)
1266 return NULL_TREE;
1267 expr = TREE_OPERAND (expr, 0);
1268 obj = expr;
1269 expr = get_ref_base_and_extent (expr, offset, &size, &max_size);
1271 if (TREE_CODE (expr) != MEM_REF
1272 /* If this is a varying address, punt. */
1273 || max_size == -1
1274 || max_size != size
1275 || *offset < 0)
1276 return NULL_TREE;
1277 parm = TREE_OPERAND (expr, 0);
1278 if (TREE_CODE (parm) != SSA_NAME
1279 || !SSA_NAME_IS_DEFAULT_DEF (parm)
1280 || TREE_CODE (SSA_NAME_VAR (parm)) != PARM_DECL)
1281 return NULL_TREE;
1283 *offset += mem_ref_offset (expr).to_short_addr () * BITS_PER_UNIT;
1284 *obj_p = obj;
1285 return expr;
1289 /* Given that an actual argument is an SSA_NAME that is a result of a phi
1290 statement PHI, try to find out whether NAME is in fact a
1291 multiple-inheritance typecast from a descendant into an ancestor of a formal
1292 parameter and thus can be described by an ancestor jump function and if so,
1293 write the appropriate function into JFUNC.
1295 Essentially we want to match the following pattern:
1297 if (obj_2(D) != 0B)
1298 goto <bb 3>;
1299 else
1300 goto <bb 4>;
1302 <bb 3>:
1303 iftmp.1_3 = &obj_2(D)->D.1762;
1305 <bb 4>:
1306 # iftmp.1_1 = PHI <iftmp.1_3(3), 0B(2)>
1307 D.1879_6 = middleman_1 (iftmp.1_1, i_5(D));
1308 return D.1879_6; */
1310 static void
1311 compute_complex_ancestor_jump_func (struct func_body_info *fbi,
1312 struct ipa_node_params *info,
1313 struct ipa_jump_func *jfunc,
1314 gcall *call, gphi *phi)
1316 HOST_WIDE_INT offset;
1317 gimple assign, cond;
1318 basic_block phi_bb, assign_bb, cond_bb;
1319 tree tmp, parm, expr, obj;
1320 int index, i;
1322 if (gimple_phi_num_args (phi) != 2)
1323 return;
1325 if (integer_zerop (PHI_ARG_DEF (phi, 1)))
1326 tmp = PHI_ARG_DEF (phi, 0);
1327 else if (integer_zerop (PHI_ARG_DEF (phi, 0)))
1328 tmp = PHI_ARG_DEF (phi, 1);
1329 else
1330 return;
1331 if (TREE_CODE (tmp) != SSA_NAME
1332 || SSA_NAME_IS_DEFAULT_DEF (tmp)
1333 || !POINTER_TYPE_P (TREE_TYPE (tmp))
1334 || TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) != RECORD_TYPE)
1335 return;
1337 assign = SSA_NAME_DEF_STMT (tmp);
1338 assign_bb = gimple_bb (assign);
1339 if (!single_pred_p (assign_bb))
1340 return;
1341 expr = get_ancestor_addr_info (assign, &obj, &offset);
1342 if (!expr)
1343 return;
1344 parm = TREE_OPERAND (expr, 0);
1345 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (parm));
1346 if (index < 0)
1347 return;
1349 cond_bb = single_pred (assign_bb);
1350 cond = last_stmt (cond_bb);
1351 if (!cond
1352 || gimple_code (cond) != GIMPLE_COND
1353 || gimple_cond_code (cond) != NE_EXPR
1354 || gimple_cond_lhs (cond) != parm
1355 || !integer_zerop (gimple_cond_rhs (cond)))
1356 return;
1358 phi_bb = gimple_bb (phi);
1359 for (i = 0; i < 2; i++)
1361 basic_block pred = EDGE_PRED (phi_bb, i)->src;
1362 if (pred != assign_bb && pred != cond_bb)
1363 return;
1366 ipa_set_ancestor_jf (jfunc, offset, index,
1367 parm_ref_data_pass_through_p (fbi, index, call, parm));
1370 /* Inspect the given TYPE and return true iff it has the same structure (the
1371 same number of fields of the same types) as a C++ member pointer. If
1372 METHOD_PTR and DELTA are non-NULL, store the trees representing the
1373 corresponding fields there. */
1375 static bool
1376 type_like_member_ptr_p (tree type, tree *method_ptr, tree *delta)
1378 tree fld;
1380 if (TREE_CODE (type) != RECORD_TYPE)
1381 return false;
1383 fld = TYPE_FIELDS (type);
1384 if (!fld || !POINTER_TYPE_P (TREE_TYPE (fld))
1385 || TREE_CODE (TREE_TYPE (TREE_TYPE (fld))) != METHOD_TYPE
1386 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
1387 return false;
1389 if (method_ptr)
1390 *method_ptr = fld;
1392 fld = DECL_CHAIN (fld);
1393 if (!fld || INTEGRAL_TYPE_P (fld)
1394 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
1395 return false;
1396 if (delta)
1397 *delta = fld;
1399 if (DECL_CHAIN (fld))
1400 return false;
1402 return true;
1405 /* If RHS is an SSA_NAME and it is defined by a simple copy assign statement,
1406 return the rhs of its defining statement. Otherwise return RHS as it
1407 is. */
1409 static inline tree
1410 get_ssa_def_if_simple_copy (tree rhs)
1412 while (TREE_CODE (rhs) == SSA_NAME && !SSA_NAME_IS_DEFAULT_DEF (rhs))
1414 gimple def_stmt = SSA_NAME_DEF_STMT (rhs);
1416 if (gimple_assign_single_p (def_stmt))
1417 rhs = gimple_assign_rhs1 (def_stmt);
1418 else
1419 break;
1421 return rhs;
1424 /* Simple linked list, describing known contents of an aggregate beforere
1425 call. */
1427 struct ipa_known_agg_contents_list
1429 /* Offset and size of the described part of the aggregate. */
1430 HOST_WIDE_INT offset, size;
1431 /* Known constant value or NULL if the contents is known to be unknown. */
1432 tree constant;
1433 /* Pointer to the next structure in the list. */
1434 struct ipa_known_agg_contents_list *next;
1437 /* Find the proper place in linked list of ipa_known_agg_contents_list
1438 structures where to put a new one with the given LHS_OFFSET and LHS_SIZE,
1439 unless there is a partial overlap, in which case return NULL, or such
1440 element is already there, in which case set *ALREADY_THERE to true. */
1442 static struct ipa_known_agg_contents_list **
1443 get_place_in_agg_contents_list (struct ipa_known_agg_contents_list **list,
1444 HOST_WIDE_INT lhs_offset,
1445 HOST_WIDE_INT lhs_size,
1446 bool *already_there)
1448 struct ipa_known_agg_contents_list **p = list;
1449 while (*p && (*p)->offset < lhs_offset)
1451 if ((*p)->offset + (*p)->size > lhs_offset)
1452 return NULL;
1453 p = &(*p)->next;
1456 if (*p && (*p)->offset < lhs_offset + lhs_size)
1458 if ((*p)->offset == lhs_offset && (*p)->size == lhs_size)
1459 /* We already know this value is subsequently overwritten with
1460 something else. */
1461 *already_there = true;
1462 else
1463 /* Otherwise this is a partial overlap which we cannot
1464 represent. */
1465 return NULL;
1467 return p;
1470 /* Build aggregate jump function from LIST, assuming there are exactly
1471 CONST_COUNT constant entries there and that th offset of the passed argument
1472 is ARG_OFFSET and store it into JFUNC. */
1474 static void
1475 build_agg_jump_func_from_list (struct ipa_known_agg_contents_list *list,
1476 int const_count, HOST_WIDE_INT arg_offset,
1477 struct ipa_jump_func *jfunc)
1479 vec_alloc (jfunc->agg.items, const_count);
1480 while (list)
1482 if (list->constant)
1484 struct ipa_agg_jf_item item;
1485 item.offset = list->offset - arg_offset;
1486 gcc_assert ((item.offset % BITS_PER_UNIT) == 0);
1487 item.value = unshare_expr_without_location (list->constant);
1488 jfunc->agg.items->quick_push (item);
1490 list = list->next;
1494 /* Traverse statements from CALL backwards, scanning whether an aggregate given
1495 in ARG is filled in with constant values. ARG can either be an aggregate
1496 expression or a pointer to an aggregate. ARG_TYPE is the type of the
1497 aggregate. JFUNC is the jump function into which the constants are
1498 subsequently stored. */
1500 static void
1501 determine_locally_known_aggregate_parts (gcall *call, tree arg,
1502 tree arg_type,
1503 struct ipa_jump_func *jfunc)
1505 struct ipa_known_agg_contents_list *list = NULL;
1506 int item_count = 0, const_count = 0;
1507 HOST_WIDE_INT arg_offset, arg_size;
1508 gimple_stmt_iterator gsi;
1509 tree arg_base;
1510 bool check_ref, by_ref;
1511 ao_ref r;
1513 /* The function operates in three stages. First, we prepare check_ref, r,
1514 arg_base and arg_offset based on what is actually passed as an actual
1515 argument. */
1517 if (POINTER_TYPE_P (arg_type))
1519 by_ref = true;
1520 if (TREE_CODE (arg) == SSA_NAME)
1522 tree type_size;
1523 if (!tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (arg_type))))
1524 return;
1525 check_ref = true;
1526 arg_base = arg;
1527 arg_offset = 0;
1528 type_size = TYPE_SIZE (TREE_TYPE (arg_type));
1529 arg_size = tree_to_uhwi (type_size);
1530 ao_ref_init_from_ptr_and_size (&r, arg_base, NULL_TREE);
1532 else if (TREE_CODE (arg) == ADDR_EXPR)
1534 HOST_WIDE_INT arg_max_size;
1536 arg = TREE_OPERAND (arg, 0);
1537 arg_base = get_ref_base_and_extent (arg, &arg_offset, &arg_size,
1538 &arg_max_size);
1539 if (arg_max_size == -1
1540 || arg_max_size != arg_size
1541 || arg_offset < 0)
1542 return;
1543 if (DECL_P (arg_base))
1545 check_ref = false;
1546 ao_ref_init (&r, arg_base);
1548 else
1549 return;
1551 else
1552 return;
1554 else
1556 HOST_WIDE_INT arg_max_size;
1558 gcc_checking_assert (AGGREGATE_TYPE_P (TREE_TYPE (arg)));
1560 by_ref = false;
1561 check_ref = false;
1562 arg_base = get_ref_base_and_extent (arg, &arg_offset, &arg_size,
1563 &arg_max_size);
1564 if (arg_max_size == -1
1565 || arg_max_size != arg_size
1566 || arg_offset < 0)
1567 return;
1569 ao_ref_init (&r, arg);
1572 /* Second stage walks back the BB, looks at individual statements and as long
1573 as it is confident of how the statements affect contents of the
1574 aggregates, it builds a sorted linked list of ipa_agg_jf_list structures
1575 describing it. */
1576 gsi = gsi_for_stmt (call);
1577 gsi_prev (&gsi);
1578 for (; !gsi_end_p (gsi); gsi_prev (&gsi))
1580 struct ipa_known_agg_contents_list *n, **p;
1581 gimple stmt = gsi_stmt (gsi);
1582 HOST_WIDE_INT lhs_offset, lhs_size, lhs_max_size;
1583 tree lhs, rhs, lhs_base;
1585 if (!stmt_may_clobber_ref_p_1 (stmt, &r))
1586 continue;
1587 if (!gimple_assign_single_p (stmt))
1588 break;
1590 lhs = gimple_assign_lhs (stmt);
1591 rhs = gimple_assign_rhs1 (stmt);
1592 if (!is_gimple_reg_type (TREE_TYPE (rhs))
1593 || TREE_CODE (lhs) == BIT_FIELD_REF
1594 || contains_bitfld_component_ref_p (lhs))
1595 break;
1597 lhs_base = get_ref_base_and_extent (lhs, &lhs_offset, &lhs_size,
1598 &lhs_max_size);
1599 if (lhs_max_size == -1
1600 || lhs_max_size != lhs_size)
1601 break;
1603 if (check_ref)
1605 if (TREE_CODE (lhs_base) != MEM_REF
1606 || TREE_OPERAND (lhs_base, 0) != arg_base
1607 || !integer_zerop (TREE_OPERAND (lhs_base, 1)))
1608 break;
1610 else if (lhs_base != arg_base)
1612 if (DECL_P (lhs_base))
1613 continue;
1614 else
1615 break;
1618 bool already_there = false;
1619 p = get_place_in_agg_contents_list (&list, lhs_offset, lhs_size,
1620 &already_there);
1621 if (!p)
1622 break;
1623 if (already_there)
1624 continue;
1626 rhs = get_ssa_def_if_simple_copy (rhs);
1627 n = XALLOCA (struct ipa_known_agg_contents_list);
1628 n->size = lhs_size;
1629 n->offset = lhs_offset;
1630 if (is_gimple_ip_invariant (rhs))
1632 n->constant = rhs;
1633 const_count++;
1635 else
1636 n->constant = NULL_TREE;
1637 n->next = *p;
1638 *p = n;
1640 item_count++;
1641 if (const_count == PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS)
1642 || item_count == 2 * PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS))
1643 break;
1646 /* Third stage just goes over the list and creates an appropriate vector of
1647 ipa_agg_jf_item structures out of it, of sourse only if there are
1648 any known constants to begin with. */
1650 if (const_count)
1652 jfunc->agg.by_ref = by_ref;
1653 build_agg_jump_func_from_list (list, const_count, arg_offset, jfunc);
1657 static tree
1658 ipa_get_callee_param_type (struct cgraph_edge *e, int i)
1660 int n;
1661 tree type = (e->callee
1662 ? TREE_TYPE (e->callee->decl)
1663 : gimple_call_fntype (e->call_stmt));
1664 tree t = TYPE_ARG_TYPES (type);
1666 for (n = 0; n < i; n++)
1668 if (!t)
1669 break;
1670 t = TREE_CHAIN (t);
1672 if (t)
1673 return TREE_VALUE (t);
1674 if (!e->callee)
1675 return NULL;
1676 t = DECL_ARGUMENTS (e->callee->decl);
1677 for (n = 0; n < i; n++)
1679 if (!t)
1680 return NULL;
1681 t = TREE_CHAIN (t);
1683 if (t)
1684 return TREE_TYPE (t);
1685 return NULL;
1688 /* Compute jump function for all arguments of callsite CS and insert the
1689 information in the jump_functions array in the ipa_edge_args corresponding
1690 to this callsite. */
1692 static void
1693 ipa_compute_jump_functions_for_edge (struct func_body_info *fbi,
1694 struct cgraph_edge *cs)
1696 struct ipa_node_params *info = IPA_NODE_REF (cs->caller);
1697 struct ipa_edge_args *args = IPA_EDGE_REF (cs);
1698 gcall *call = cs->call_stmt;
1699 int n, arg_num = gimple_call_num_args (call);
1700 bool useful_context = false;
1702 if (arg_num == 0 || args->jump_functions)
1703 return;
1704 vec_safe_grow_cleared (args->jump_functions, arg_num);
1705 if (flag_devirtualize)
1706 vec_safe_grow_cleared (args->polymorphic_call_contexts, arg_num);
1708 if (gimple_call_internal_p (call))
1709 return;
1710 if (ipa_func_spec_opts_forbid_analysis_p (cs->caller))
1711 return;
1713 for (n = 0; n < arg_num; n++)
1715 struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, n);
1716 tree arg = gimple_call_arg (call, n);
1717 tree param_type = ipa_get_callee_param_type (cs, n);
1718 if (flag_devirtualize && POINTER_TYPE_P (TREE_TYPE (arg)))
1720 tree instance;
1721 struct ipa_polymorphic_call_context context (cs->caller->decl,
1722 arg, cs->call_stmt,
1723 &instance);
1724 context.get_dynamic_type (instance, arg, NULL, cs->call_stmt);
1725 *ipa_get_ith_polymorhic_call_context (args, n) = context;
1726 if (!context.useless_p ())
1727 useful_context = true;
1730 if (POINTER_TYPE_P (TREE_TYPE(arg)))
1732 unsigned HOST_WIDE_INT hwi_bitpos;
1733 unsigned align;
1735 if (get_pointer_alignment_1 (arg, &align, &hwi_bitpos)
1736 && align % BITS_PER_UNIT == 0
1737 && hwi_bitpos % BITS_PER_UNIT == 0)
1739 jfunc->alignment.known = true;
1740 jfunc->alignment.align = align / BITS_PER_UNIT;
1741 jfunc->alignment.misalign = hwi_bitpos / BITS_PER_UNIT;
1743 else
1744 gcc_assert (!jfunc->alignment.known);
1746 else
1747 gcc_assert (!jfunc->alignment.known);
1749 if (is_gimple_ip_invariant (arg))
1750 ipa_set_jf_constant (jfunc, arg, cs);
1751 else if (!is_gimple_reg_type (TREE_TYPE (arg))
1752 && TREE_CODE (arg) == PARM_DECL)
1754 int index = ipa_get_param_decl_index (info, arg);
1756 gcc_assert (index >=0);
1757 /* Aggregate passed by value, check for pass-through, otherwise we
1758 will attempt to fill in aggregate contents later in this
1759 for cycle. */
1760 if (parm_preserved_before_stmt_p (fbi, index, call, arg))
1762 ipa_set_jf_simple_pass_through (jfunc, index, false);
1763 continue;
1766 else if (TREE_CODE (arg) == SSA_NAME)
1768 if (SSA_NAME_IS_DEFAULT_DEF (arg))
1770 int index = ipa_get_param_decl_index (info, SSA_NAME_VAR (arg));
1771 if (index >= 0)
1773 bool agg_p;
1774 agg_p = parm_ref_data_pass_through_p (fbi, index, call, arg);
1775 ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
1778 else
1780 gimple stmt = SSA_NAME_DEF_STMT (arg);
1781 if (is_gimple_assign (stmt))
1782 compute_complex_assign_jump_func (fbi, info, jfunc,
1783 call, stmt, arg, param_type);
1784 else if (gimple_code (stmt) == GIMPLE_PHI)
1785 compute_complex_ancestor_jump_func (fbi, info, jfunc,
1786 call,
1787 as_a <gphi *> (stmt));
1791 /* If ARG is pointer, we can not use its type to determine the type of aggregate
1792 passed (because type conversions are ignored in gimple). Usually we can
1793 safely get type from function declaration, but in case of K&R prototypes or
1794 variadic functions we can try our luck with type of the pointer passed.
1795 TODO: Since we look for actual initialization of the memory object, we may better
1796 work out the type based on the memory stores we find. */
1797 if (!param_type)
1798 param_type = TREE_TYPE (arg);
1800 if ((jfunc->type != IPA_JF_PASS_THROUGH
1801 || !ipa_get_jf_pass_through_agg_preserved (jfunc))
1802 && (jfunc->type != IPA_JF_ANCESTOR
1803 || !ipa_get_jf_ancestor_agg_preserved (jfunc))
1804 && (AGGREGATE_TYPE_P (TREE_TYPE (arg))
1805 || POINTER_TYPE_P (param_type)))
1806 determine_locally_known_aggregate_parts (call, arg, param_type, jfunc);
1808 if (!useful_context)
1809 vec_free (args->polymorphic_call_contexts);
1812 /* Compute jump functions for all edges - both direct and indirect - outgoing
1813 from BB. */
1815 static void
1816 ipa_compute_jump_functions_for_bb (struct func_body_info *fbi, basic_block bb)
1818 struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
1819 int i;
1820 struct cgraph_edge *cs;
1822 FOR_EACH_VEC_ELT_REVERSE (bi->cg_edges, i, cs)
1824 struct cgraph_node *callee = cs->callee;
1826 if (callee)
1828 callee->ultimate_alias_target ();
1829 /* We do not need to bother analyzing calls to unknown functions
1830 unless they may become known during lto/whopr. */
1831 if (!callee->definition && !flag_lto)
1832 continue;
1834 ipa_compute_jump_functions_for_edge (fbi, cs);
1838 /* If STMT looks like a statement loading a value from a member pointer formal
1839 parameter, return that parameter and store the offset of the field to
1840 *OFFSET_P, if it is non-NULL. Otherwise return NULL (but *OFFSET_P still
1841 might be clobbered). If USE_DELTA, then we look for a use of the delta
1842 field rather than the pfn. */
1844 static tree
1845 ipa_get_stmt_member_ptr_load_param (gimple stmt, bool use_delta,
1846 HOST_WIDE_INT *offset_p)
1848 tree rhs, rec, ref_field, ref_offset, fld, ptr_field, delta_field;
1850 if (!gimple_assign_single_p (stmt))
1851 return NULL_TREE;
1853 rhs = gimple_assign_rhs1 (stmt);
1854 if (TREE_CODE (rhs) == COMPONENT_REF)
1856 ref_field = TREE_OPERAND (rhs, 1);
1857 rhs = TREE_OPERAND (rhs, 0);
1859 else
1860 ref_field = NULL_TREE;
1861 if (TREE_CODE (rhs) != MEM_REF)
1862 return NULL_TREE;
1863 rec = TREE_OPERAND (rhs, 0);
1864 if (TREE_CODE (rec) != ADDR_EXPR)
1865 return NULL_TREE;
1866 rec = TREE_OPERAND (rec, 0);
1867 if (TREE_CODE (rec) != PARM_DECL
1868 || !type_like_member_ptr_p (TREE_TYPE (rec), &ptr_field, &delta_field))
1869 return NULL_TREE;
1870 ref_offset = TREE_OPERAND (rhs, 1);
1872 if (use_delta)
1873 fld = delta_field;
1874 else
1875 fld = ptr_field;
1876 if (offset_p)
1877 *offset_p = int_bit_position (fld);
1879 if (ref_field)
1881 if (integer_nonzerop (ref_offset))
1882 return NULL_TREE;
1883 return ref_field == fld ? rec : NULL_TREE;
1885 else
1886 return tree_int_cst_equal (byte_position (fld), ref_offset) ? rec
1887 : NULL_TREE;
1890 /* Returns true iff T is an SSA_NAME defined by a statement. */
1892 static bool
1893 ipa_is_ssa_with_stmt_def (tree t)
1895 if (TREE_CODE (t) == SSA_NAME
1896 && !SSA_NAME_IS_DEFAULT_DEF (t))
1897 return true;
1898 else
1899 return false;
1902 /* Find the indirect call graph edge corresponding to STMT and mark it as a
1903 call to a parameter number PARAM_INDEX. NODE is the caller. Return the
1904 indirect call graph edge. */
1906 static struct cgraph_edge *
1907 ipa_note_param_call (struct cgraph_node *node, int param_index,
1908 gcall *stmt)
1910 struct cgraph_edge *cs;
1912 cs = node->get_edge (stmt);
1913 cs->indirect_info->param_index = param_index;
1914 cs->indirect_info->agg_contents = 0;
1915 cs->indirect_info->member_ptr = 0;
1916 return cs;
1919 /* Analyze the CALL and examine uses of formal parameters of the caller NODE
1920 (described by INFO). PARMS_AINFO is a pointer to a vector containing
1921 intermediate information about each formal parameter. Currently it checks
1922 whether the call calls a pointer that is a formal parameter and if so, the
1923 parameter is marked with the called flag and an indirect call graph edge
1924 describing the call is created. This is very simple for ordinary pointers
1925 represented in SSA but not-so-nice when it comes to member pointers. The
1926 ugly part of this function does nothing more than trying to match the
1927 pattern of such a call. An example of such a pattern is the gimple dump
1928 below, the call is on the last line:
1930 <bb 2>:
1931 f$__delta_5 = f.__delta;
1932 f$__pfn_24 = f.__pfn;
1935 <bb 2>:
1936 f$__delta_5 = MEM[(struct *)&f];
1937 f$__pfn_24 = MEM[(struct *)&f + 4B];
1939 and a few lines below:
1941 <bb 5>
1942 D.2496_3 = (int) f$__pfn_24;
1943 D.2497_4 = D.2496_3 & 1;
1944 if (D.2497_4 != 0)
1945 goto <bb 3>;
1946 else
1947 goto <bb 4>;
1949 <bb 6>:
1950 D.2500_7 = (unsigned int) f$__delta_5;
1951 D.2501_8 = &S + D.2500_7;
1952 D.2502_9 = (int (*__vtbl_ptr_type) (void) * *) D.2501_8;
1953 D.2503_10 = *D.2502_9;
1954 D.2504_12 = f$__pfn_24 + -1;
1955 D.2505_13 = (unsigned int) D.2504_12;
1956 D.2506_14 = D.2503_10 + D.2505_13;
1957 D.2507_15 = *D.2506_14;
1958 iftmp.11_16 = (String:: *) D.2507_15;
1960 <bb 7>:
1961 # iftmp.11_1 = PHI <iftmp.11_16(3), f$__pfn_24(2)>
1962 D.2500_19 = (unsigned int) f$__delta_5;
1963 D.2508_20 = &S + D.2500_19;
1964 D.2493_21 = iftmp.11_1 (D.2508_20, 4);
1966 Such patterns are results of simple calls to a member pointer:
1968 int doprinting (int (MyString::* f)(int) const)
1970 MyString S ("somestring");
1972 return (S.*f)(4);
1975 Moreover, the function also looks for called pointers loaded from aggregates
1976 passed by value or reference. */
1978 static void
1979 ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gcall *call,
1980 tree target)
1982 struct ipa_node_params *info = fbi->info;
1983 HOST_WIDE_INT offset;
1984 bool by_ref;
1986 if (SSA_NAME_IS_DEFAULT_DEF (target))
1988 tree var = SSA_NAME_VAR (target);
1989 int index = ipa_get_param_decl_index (info, var);
1990 if (index >= 0)
1991 ipa_note_param_call (fbi->node, index, call);
1992 return;
1995 int index;
1996 gimple def = SSA_NAME_DEF_STMT (target);
1997 if (gimple_assign_single_p (def)
1998 && ipa_load_from_parm_agg_1 (fbi, info->descriptors, def,
1999 gimple_assign_rhs1 (def), &index, &offset,
2000 NULL, &by_ref))
2002 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
2003 cs->indirect_info->offset = offset;
2004 cs->indirect_info->agg_contents = 1;
2005 cs->indirect_info->by_ref = by_ref;
2006 return;
2009 /* Now we need to try to match the complex pattern of calling a member
2010 pointer. */
2011 if (gimple_code (def) != GIMPLE_PHI
2012 || gimple_phi_num_args (def) != 2
2013 || !POINTER_TYPE_P (TREE_TYPE (target))
2014 || TREE_CODE (TREE_TYPE (TREE_TYPE (target))) != METHOD_TYPE)
2015 return;
2017 /* First, we need to check whether one of these is a load from a member
2018 pointer that is a parameter to this function. */
2019 tree n1 = PHI_ARG_DEF (def, 0);
2020 tree n2 = PHI_ARG_DEF (def, 1);
2021 if (!ipa_is_ssa_with_stmt_def (n1) || !ipa_is_ssa_with_stmt_def (n2))
2022 return;
2023 gimple d1 = SSA_NAME_DEF_STMT (n1);
2024 gimple d2 = SSA_NAME_DEF_STMT (n2);
2026 tree rec;
2027 basic_block bb, virt_bb;
2028 basic_block join = gimple_bb (def);
2029 if ((rec = ipa_get_stmt_member_ptr_load_param (d1, false, &offset)))
2031 if (ipa_get_stmt_member_ptr_load_param (d2, false, NULL))
2032 return;
2034 bb = EDGE_PRED (join, 0)->src;
2035 virt_bb = gimple_bb (d2);
2037 else if ((rec = ipa_get_stmt_member_ptr_load_param (d2, false, &offset)))
2039 bb = EDGE_PRED (join, 1)->src;
2040 virt_bb = gimple_bb (d1);
2042 else
2043 return;
2045 /* Second, we need to check that the basic blocks are laid out in the way
2046 corresponding to the pattern. */
2048 if (!single_pred_p (virt_bb) || !single_succ_p (virt_bb)
2049 || single_pred (virt_bb) != bb
2050 || single_succ (virt_bb) != join)
2051 return;
2053 /* Third, let's see that the branching is done depending on the least
2054 significant bit of the pfn. */
2056 gimple branch = last_stmt (bb);
2057 if (!branch || gimple_code (branch) != GIMPLE_COND)
2058 return;
2060 if ((gimple_cond_code (branch) != NE_EXPR
2061 && gimple_cond_code (branch) != EQ_EXPR)
2062 || !integer_zerop (gimple_cond_rhs (branch)))
2063 return;
2065 tree cond = gimple_cond_lhs (branch);
2066 if (!ipa_is_ssa_with_stmt_def (cond))
2067 return;
2069 def = SSA_NAME_DEF_STMT (cond);
2070 if (!is_gimple_assign (def)
2071 || gimple_assign_rhs_code (def) != BIT_AND_EXPR
2072 || !integer_onep (gimple_assign_rhs2 (def)))
2073 return;
2075 cond = gimple_assign_rhs1 (def);
2076 if (!ipa_is_ssa_with_stmt_def (cond))
2077 return;
2079 def = SSA_NAME_DEF_STMT (cond);
2081 if (is_gimple_assign (def)
2082 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
2084 cond = gimple_assign_rhs1 (def);
2085 if (!ipa_is_ssa_with_stmt_def (cond))
2086 return;
2087 def = SSA_NAME_DEF_STMT (cond);
2090 tree rec2;
2091 rec2 = ipa_get_stmt_member_ptr_load_param (def,
2092 (TARGET_PTRMEMFUNC_VBIT_LOCATION
2093 == ptrmemfunc_vbit_in_delta),
2094 NULL);
2095 if (rec != rec2)
2096 return;
2098 index = ipa_get_param_decl_index (info, rec);
2099 if (index >= 0
2100 && parm_preserved_before_stmt_p (fbi, index, call, rec))
2102 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
2103 cs->indirect_info->offset = offset;
2104 cs->indirect_info->agg_contents = 1;
2105 cs->indirect_info->member_ptr = 1;
2108 return;
2111 /* Analyze a CALL to an OBJ_TYPE_REF which is passed in TARGET and if the
2112 object referenced in the expression is a formal parameter of the caller
2113 FBI->node (described by FBI->info), create a call note for the
2114 statement. */
2116 static void
2117 ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
2118 gcall *call, tree target)
2120 tree obj = OBJ_TYPE_REF_OBJECT (target);
2121 int index;
2122 HOST_WIDE_INT anc_offset;
2124 if (!flag_devirtualize)
2125 return;
2127 if (TREE_CODE (obj) != SSA_NAME)
2128 return;
2130 struct ipa_node_params *info = fbi->info;
2131 if (SSA_NAME_IS_DEFAULT_DEF (obj))
2133 struct ipa_jump_func jfunc;
2134 if (TREE_CODE (SSA_NAME_VAR (obj)) != PARM_DECL)
2135 return;
2137 anc_offset = 0;
2138 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (obj));
2139 gcc_assert (index >= 0);
2140 if (detect_type_change_ssa (obj, obj_type_ref_class (target),
2141 call, &jfunc))
2142 return;
2144 else
2146 struct ipa_jump_func jfunc;
2147 gimple stmt = SSA_NAME_DEF_STMT (obj);
2148 tree expr;
2150 expr = get_ancestor_addr_info (stmt, &obj, &anc_offset);
2151 if (!expr)
2152 return;
2153 index = ipa_get_param_decl_index (info,
2154 SSA_NAME_VAR (TREE_OPERAND (expr, 0)));
2155 gcc_assert (index >= 0);
2156 if (detect_type_change (obj, expr, obj_type_ref_class (target),
2157 call, &jfunc, anc_offset))
2158 return;
2161 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
2162 struct cgraph_indirect_call_info *ii = cs->indirect_info;
2163 ii->offset = anc_offset;
2164 ii->otr_token = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target));
2165 ii->otr_type = obj_type_ref_class (target);
2166 ii->polymorphic = 1;
2169 /* Analyze a call statement CALL whether and how it utilizes formal parameters
2170 of the caller (described by INFO). PARMS_AINFO is a pointer to a vector
2171 containing intermediate information about each formal parameter. */
2173 static void
2174 ipa_analyze_call_uses (struct func_body_info *fbi, gcall *call)
2176 tree target = gimple_call_fn (call);
2178 if (!target
2179 || (TREE_CODE (target) != SSA_NAME
2180 && !virtual_method_call_p (target)))
2181 return;
2183 struct cgraph_edge *cs = fbi->node->get_edge (call);
2184 /* If we previously turned the call into a direct call, there is
2185 no need to analyze. */
2186 if (cs && !cs->indirect_unknown_callee)
2187 return;
2189 if (cs->indirect_info->polymorphic && flag_devirtualize)
2191 tree instance;
2192 tree target = gimple_call_fn (call);
2193 ipa_polymorphic_call_context context (current_function_decl,
2194 target, call, &instance);
2196 gcc_checking_assert (cs->indirect_info->otr_type
2197 == obj_type_ref_class (target));
2198 gcc_checking_assert (cs->indirect_info->otr_token
2199 == tree_to_shwi (OBJ_TYPE_REF_TOKEN (target)));
2201 cs->indirect_info->vptr_changed
2202 = !context.get_dynamic_type (instance,
2203 OBJ_TYPE_REF_OBJECT (target),
2204 obj_type_ref_class (target), call);
2205 cs->indirect_info->context = context;
2208 if (TREE_CODE (target) == SSA_NAME)
2209 ipa_analyze_indirect_call_uses (fbi, call, target);
2210 else if (virtual_method_call_p (target))
2211 ipa_analyze_virtual_call_uses (fbi, call, target);
2215 /* Analyze the call statement STMT with respect to formal parameters (described
2216 in INFO) of caller given by FBI->NODE. Currently it only checks whether
2217 formal parameters are called. */
2219 static void
2220 ipa_analyze_stmt_uses (struct func_body_info *fbi, gimple stmt)
2222 if (is_gimple_call (stmt))
2223 ipa_analyze_call_uses (fbi, as_a <gcall *> (stmt));
2226 /* Callback of walk_stmt_load_store_addr_ops for the visit_load.
2227 If OP is a parameter declaration, mark it as used in the info structure
2228 passed in DATA. */
2230 static bool
2231 visit_ref_for_mod_analysis (gimple, tree op, tree, void *data)
2233 struct ipa_node_params *info = (struct ipa_node_params *) data;
2235 op = get_base_address (op);
2236 if (op
2237 && TREE_CODE (op) == PARM_DECL)
2239 int index = ipa_get_param_decl_index (info, op);
2240 gcc_assert (index >= 0);
2241 ipa_set_param_used (info, index, true);
2244 return false;
2247 /* Scan the statements in BB and inspect the uses of formal parameters. Store
2248 the findings in various structures of the associated ipa_node_params
2249 structure, such as parameter flags, notes etc. FBI holds various data about
2250 the function being analyzed. */
2252 static void
2253 ipa_analyze_params_uses_in_bb (struct func_body_info *fbi, basic_block bb)
2255 gimple_stmt_iterator gsi;
2256 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2258 gimple stmt = gsi_stmt (gsi);
2260 if (is_gimple_debug (stmt))
2261 continue;
2263 ipa_analyze_stmt_uses (fbi, stmt);
2264 walk_stmt_load_store_addr_ops (stmt, fbi->info,
2265 visit_ref_for_mod_analysis,
2266 visit_ref_for_mod_analysis,
2267 visit_ref_for_mod_analysis);
2269 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2270 walk_stmt_load_store_addr_ops (gsi_stmt (gsi), fbi->info,
2271 visit_ref_for_mod_analysis,
2272 visit_ref_for_mod_analysis,
2273 visit_ref_for_mod_analysis);
2276 /* Calculate controlled uses of parameters of NODE. */
2278 static void
2279 ipa_analyze_controlled_uses (struct cgraph_node *node)
2281 struct ipa_node_params *info = IPA_NODE_REF (node);
2283 for (int i = 0; i < ipa_get_param_count (info); i++)
2285 tree parm = ipa_get_param (info, i);
2286 int controlled_uses = 0;
2288 /* For SSA regs see if parameter is used. For non-SSA we compute
2289 the flag during modification analysis. */
2290 if (is_gimple_reg (parm))
2292 tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl),
2293 parm);
2294 if (ddef && !has_zero_uses (ddef))
2296 imm_use_iterator imm_iter;
2297 use_operand_p use_p;
2299 ipa_set_param_used (info, i, true);
2300 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, ddef)
2301 if (!is_gimple_call (USE_STMT (use_p)))
2303 if (!is_gimple_debug (USE_STMT (use_p)))
2305 controlled_uses = IPA_UNDESCRIBED_USE;
2306 break;
2309 else
2310 controlled_uses++;
2312 else
2313 controlled_uses = 0;
2315 else
2316 controlled_uses = IPA_UNDESCRIBED_USE;
2317 ipa_set_controlled_uses (info, i, controlled_uses);
2321 /* Free stuff in BI. */
2323 static void
2324 free_ipa_bb_info (struct ipa_bb_info *bi)
2326 bi->cg_edges.release ();
2327 bi->param_aa_statuses.release ();
2330 /* Dominator walker driving the analysis. */
2332 class analysis_dom_walker : public dom_walker
2334 public:
2335 analysis_dom_walker (struct func_body_info *fbi)
2336 : dom_walker (CDI_DOMINATORS), m_fbi (fbi) {}
2338 virtual void before_dom_children (basic_block);
2340 private:
2341 struct func_body_info *m_fbi;
2344 void
2345 analysis_dom_walker::before_dom_children (basic_block bb)
2347 ipa_analyze_params_uses_in_bb (m_fbi, bb);
2348 ipa_compute_jump_functions_for_bb (m_fbi, bb);
2351 /* Initialize the array describing properties of of formal parameters
2352 of NODE, analyze their uses and compute jump functions associated
2353 with actual arguments of calls from within NODE. */
2355 void
2356 ipa_analyze_node (struct cgraph_node *node)
2358 struct func_body_info fbi;
2359 struct ipa_node_params *info;
2361 ipa_check_create_node_params ();
2362 ipa_check_create_edge_args ();
2363 info = IPA_NODE_REF (node);
2365 if (info->analysis_done)
2366 return;
2367 info->analysis_done = 1;
2369 if (ipa_func_spec_opts_forbid_analysis_p (node))
2371 for (int i = 0; i < ipa_get_param_count (info); i++)
2373 ipa_set_param_used (info, i, true);
2374 ipa_set_controlled_uses (info, i, IPA_UNDESCRIBED_USE);
2376 return;
2379 struct function *func = DECL_STRUCT_FUNCTION (node->decl);
2380 push_cfun (func);
2381 calculate_dominance_info (CDI_DOMINATORS);
2382 ipa_initialize_node_params (node);
2383 ipa_analyze_controlled_uses (node);
2385 fbi.node = node;
2386 fbi.info = IPA_NODE_REF (node);
2387 fbi.bb_infos = vNULL;
2388 fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun));
2389 fbi.param_count = ipa_get_param_count (info);
2390 fbi.aa_walked = 0;
2392 for (struct cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
2394 ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
2395 bi->cg_edges.safe_push (cs);
2398 for (struct cgraph_edge *cs = node->indirect_calls; cs; cs = cs->next_callee)
2400 ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
2401 bi->cg_edges.safe_push (cs);
2404 analysis_dom_walker (&fbi).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
2406 int i;
2407 struct ipa_bb_info *bi;
2408 FOR_EACH_VEC_ELT (fbi.bb_infos, i, bi)
2409 free_ipa_bb_info (bi);
2410 fbi.bb_infos.release ();
2411 free_dominance_info (CDI_DOMINATORS);
2412 pop_cfun ();
2415 /* Update the jump functions associated with call graph edge E when the call
2416 graph edge CS is being inlined, assuming that E->caller is already (possibly
2417 indirectly) inlined into CS->callee and that E has not been inlined. */
2419 static void
2420 update_jump_functions_after_inlining (struct cgraph_edge *cs,
2421 struct cgraph_edge *e)
2423 struct ipa_edge_args *top = IPA_EDGE_REF (cs);
2424 struct ipa_edge_args *args = IPA_EDGE_REF (e);
2425 int count = ipa_get_cs_argument_count (args);
2426 int i;
2428 for (i = 0; i < count; i++)
2430 struct ipa_jump_func *dst = ipa_get_ith_jump_func (args, i);
2431 struct ipa_polymorphic_call_context *dst_ctx
2432 = ipa_get_ith_polymorhic_call_context (args, i);
2434 if (dst->type == IPA_JF_ANCESTOR)
2436 struct ipa_jump_func *src;
2437 int dst_fid = dst->value.ancestor.formal_id;
2438 struct ipa_polymorphic_call_context *src_ctx
2439 = ipa_get_ith_polymorhic_call_context (top, dst_fid);
2441 /* Variable number of arguments can cause havoc if we try to access
2442 one that does not exist in the inlined edge. So make sure we
2443 don't. */
2444 if (dst_fid >= ipa_get_cs_argument_count (top))
2446 ipa_set_jf_unknown (dst);
2447 continue;
2450 src = ipa_get_ith_jump_func (top, dst_fid);
2452 if (src_ctx && !src_ctx->useless_p ())
2454 struct ipa_polymorphic_call_context ctx = *src_ctx;
2456 /* TODO: Make type preserved safe WRT contexts. */
2457 if (!ipa_get_jf_ancestor_type_preserved (dst))
2458 ctx.possible_dynamic_type_change (e->in_polymorphic_cdtor);
2459 ctx.offset_by (dst->value.ancestor.offset);
2460 if (!ctx.useless_p ())
2462 vec_safe_grow_cleared (args->polymorphic_call_contexts,
2463 count);
2464 dst_ctx = ipa_get_ith_polymorhic_call_context (args, i);
2466 dst_ctx->combine_with (ctx);
2469 if (src->agg.items
2470 && (dst->value.ancestor.agg_preserved || !src->agg.by_ref))
2472 struct ipa_agg_jf_item *item;
2473 int j;
2475 /* Currently we do not produce clobber aggregate jump functions,
2476 replace with merging when we do. */
2477 gcc_assert (!dst->agg.items);
2479 dst->agg.items = vec_safe_copy (src->agg.items);
2480 dst->agg.by_ref = src->agg.by_ref;
2481 FOR_EACH_VEC_SAFE_ELT (dst->agg.items, j, item)
2482 item->offset -= dst->value.ancestor.offset;
2485 if (src->type == IPA_JF_PASS_THROUGH
2486 && src->value.pass_through.operation == NOP_EXPR)
2488 dst->value.ancestor.formal_id = src->value.pass_through.formal_id;
2489 dst->value.ancestor.agg_preserved &=
2490 src->value.pass_through.agg_preserved;
2492 else if (src->type == IPA_JF_ANCESTOR)
2494 dst->value.ancestor.formal_id = src->value.ancestor.formal_id;
2495 dst->value.ancestor.offset += src->value.ancestor.offset;
2496 dst->value.ancestor.agg_preserved &=
2497 src->value.ancestor.agg_preserved;
2499 else
2500 ipa_set_jf_unknown (dst);
2502 else if (dst->type == IPA_JF_PASS_THROUGH)
2504 struct ipa_jump_func *src;
2505 /* We must check range due to calls with variable number of arguments
2506 and we cannot combine jump functions with operations. */
2507 if (dst->value.pass_through.operation == NOP_EXPR
2508 && (dst->value.pass_through.formal_id
2509 < ipa_get_cs_argument_count (top)))
2511 int dst_fid = dst->value.pass_through.formal_id;
2512 src = ipa_get_ith_jump_func (top, dst_fid);
2513 bool dst_agg_p = ipa_get_jf_pass_through_agg_preserved (dst);
2514 struct ipa_polymorphic_call_context *src_ctx
2515 = ipa_get_ith_polymorhic_call_context (top, dst_fid);
2517 if (src_ctx && !src_ctx->useless_p ())
2519 struct ipa_polymorphic_call_context ctx = *src_ctx;
2521 /* TODO: Make type preserved safe WRT contexts. */
2522 if (!ipa_get_jf_pass_through_type_preserved (dst))
2523 ctx.possible_dynamic_type_change (e->in_polymorphic_cdtor);
2524 if (!ctx.useless_p ())
2526 if (!dst_ctx)
2528 vec_safe_grow_cleared (args->polymorphic_call_contexts,
2529 count);
2530 dst_ctx = ipa_get_ith_polymorhic_call_context (args, i);
2532 dst_ctx->combine_with (ctx);
2535 switch (src->type)
2537 case IPA_JF_UNKNOWN:
2538 ipa_set_jf_unknown (dst);
2539 break;
2540 case IPA_JF_CONST:
2541 ipa_set_jf_cst_copy (dst, src);
2542 break;
2544 case IPA_JF_PASS_THROUGH:
2546 int formal_id = ipa_get_jf_pass_through_formal_id (src);
2547 enum tree_code operation;
2548 operation = ipa_get_jf_pass_through_operation (src);
2550 if (operation == NOP_EXPR)
2552 bool agg_p;
2553 agg_p = dst_agg_p
2554 && ipa_get_jf_pass_through_agg_preserved (src);
2555 ipa_set_jf_simple_pass_through (dst, formal_id, agg_p);
2557 else
2559 tree operand = ipa_get_jf_pass_through_operand (src);
2560 ipa_set_jf_arith_pass_through (dst, formal_id, operand,
2561 operation);
2563 break;
2565 case IPA_JF_ANCESTOR:
2567 bool agg_p;
2568 agg_p = dst_agg_p
2569 && ipa_get_jf_ancestor_agg_preserved (src);
2570 ipa_set_ancestor_jf (dst,
2571 ipa_get_jf_ancestor_offset (src),
2572 ipa_get_jf_ancestor_formal_id (src),
2573 agg_p);
2574 break;
2576 default:
2577 gcc_unreachable ();
2580 if (src->agg.items
2581 && (dst_agg_p || !src->agg.by_ref))
2583 /* Currently we do not produce clobber aggregate jump
2584 functions, replace with merging when we do. */
2585 gcc_assert (!dst->agg.items);
2587 dst->agg.by_ref = src->agg.by_ref;
2588 dst->agg.items = vec_safe_copy (src->agg.items);
2591 else
2592 ipa_set_jf_unknown (dst);
2597 /* If TARGET is an addr_expr of a function declaration, make it the
2598 (SPECULATIVE)destination of an indirect edge IE and return the edge.
2599 Otherwise, return NULL. */
2601 struct cgraph_edge *
2602 ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
2603 bool speculative)
2605 struct cgraph_node *callee;
2606 struct inline_edge_summary *es = inline_edge_summary (ie);
2607 bool unreachable = false;
2609 if (TREE_CODE (target) == ADDR_EXPR)
2610 target = TREE_OPERAND (target, 0);
2611 if (TREE_CODE (target) != FUNCTION_DECL)
2613 target = canonicalize_constructor_val (target, NULL);
2614 if (!target || TREE_CODE (target) != FUNCTION_DECL)
2616 /* Member pointer call that goes through a VMT lookup. */
2617 if (ie->indirect_info->member_ptr
2618 /* Or if target is not an invariant expression and we do not
2619 know if it will evaulate to function at runtime.
2620 This can happen when folding through &VAR, where &VAR
2621 is IP invariant, but VAR itself is not.
2623 TODO: Revisit this when GCC 5 is branched. It seems that
2624 member_ptr check is not needed and that we may try to fold
2625 the expression and see if VAR is readonly. */
2626 || !is_gimple_ip_invariant (target))
2628 if (dump_enabled_p ())
2630 location_t loc = gimple_location_safe (ie->call_stmt);
2631 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
2632 "discovered direct call non-invariant "
2633 "%s/%i\n",
2634 ie->caller->name (), ie->caller->order);
2636 return NULL;
2640 if (dump_enabled_p ())
2642 location_t loc = gimple_location_safe (ie->call_stmt);
2643 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
2644 "discovered direct call to non-function in %s/%i, "
2645 "making it __builtin_unreachable\n",
2646 ie->caller->name (), ie->caller->order);
2649 target = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
2650 callee = cgraph_node::get_create (target);
2651 unreachable = true;
2653 else
2654 callee = cgraph_node::get (target);
2656 else
2657 callee = cgraph_node::get (target);
2659 /* Because may-edges are not explicitely represented and vtable may be external,
2660 we may create the first reference to the object in the unit. */
2661 if (!callee || callee->global.inlined_to)
2664 /* We are better to ensure we can refer to it.
2665 In the case of static functions we are out of luck, since we already
2666 removed its body. In the case of public functions we may or may
2667 not introduce the reference. */
2668 if (!canonicalize_constructor_val (target, NULL)
2669 || !TREE_PUBLIC (target))
2671 if (dump_file)
2672 fprintf (dump_file, "ipa-prop: Discovered call to a known target "
2673 "(%s/%i -> %s/%i) but can not refer to it. Giving up.\n",
2674 xstrdup_for_dump (ie->caller->name ()),
2675 ie->caller->order,
2676 xstrdup_for_dump (ie->callee->name ()),
2677 ie->callee->order);
2678 return NULL;
2680 callee = cgraph_node::get_create (target);
2683 /* If the edge is already speculated. */
2684 if (speculative && ie->speculative)
2686 struct cgraph_edge *e2;
2687 struct ipa_ref *ref;
2688 ie->speculative_call_info (e2, ie, ref);
2689 if (e2->callee->ultimate_alias_target ()
2690 != callee->ultimate_alias_target ())
2692 if (dump_file)
2693 fprintf (dump_file, "ipa-prop: Discovered call to a speculative target "
2694 "(%s/%i -> %s/%i) but the call is already speculated to %s/%i. Giving up.\n",
2695 xstrdup_for_dump (ie->caller->name ()),
2696 ie->caller->order,
2697 xstrdup_for_dump (callee->name ()),
2698 callee->order,
2699 xstrdup_for_dump (e2->callee->name ()),
2700 e2->callee->order);
2702 else
2704 if (dump_file)
2705 fprintf (dump_file, "ipa-prop: Discovered call to a speculative target "
2706 "(%s/%i -> %s/%i) this agree with previous speculation.\n",
2707 xstrdup_for_dump (ie->caller->name ()),
2708 ie->caller->order,
2709 xstrdup_for_dump (callee->name ()),
2710 callee->order);
2712 return NULL;
2715 if (!dbg_cnt (devirt))
2716 return NULL;
2718 ipa_check_create_node_params ();
2720 /* We can not make edges to inline clones. It is bug that someone removed
2721 the cgraph node too early. */
2722 gcc_assert (!callee->global.inlined_to);
2724 if (dump_file && !unreachable)
2726 fprintf (dump_file, "ipa-prop: Discovered %s call to a %s target "
2727 "(%s/%i -> %s/%i), for stmt ",
2728 ie->indirect_info->polymorphic ? "a virtual" : "an indirect",
2729 speculative ? "speculative" : "known",
2730 xstrdup_for_dump (ie->caller->name ()),
2731 ie->caller->order,
2732 xstrdup_for_dump (callee->name ()),
2733 callee->order);
2734 if (ie->call_stmt)
2735 print_gimple_stmt (dump_file, ie->call_stmt, 2, TDF_SLIM);
2736 else
2737 fprintf (dump_file, "with uid %i\n", ie->lto_stmt_uid);
2739 if (dump_enabled_p ())
2741 location_t loc = gimple_location_safe (ie->call_stmt);
2743 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
2744 "converting indirect call in %s to direct call to %s\n",
2745 ie->caller->name (), callee->name ());
2747 if (!speculative)
2749 struct cgraph_edge *orig = ie;
2750 ie = ie->make_direct (callee);
2751 /* If we resolved speculative edge the cost is already up to date
2752 for direct call (adjusted by inline_edge_duplication_hook). */
2753 if (ie == orig)
2755 es = inline_edge_summary (ie);
2756 es->call_stmt_size -= (eni_size_weights.indirect_call_cost
2757 - eni_size_weights.call_cost);
2758 es->call_stmt_time -= (eni_time_weights.indirect_call_cost
2759 - eni_time_weights.call_cost);
2762 else
2764 if (!callee->can_be_discarded_p ())
2766 cgraph_node *alias;
2767 alias = dyn_cast<cgraph_node *> (callee->noninterposable_alias ());
2768 if (alias)
2769 callee = alias;
2771 /* make_speculative will update ie's cost to direct call cost. */
2772 ie = ie->make_speculative
2773 (callee, ie->count * 8 / 10, ie->frequency * 8 / 10);
2776 return ie;
2779 /* Retrieve value from aggregate jump function AGG for the given OFFSET or
2780 return NULL if there is not any. BY_REF specifies whether the value has to
2781 be passed by reference or by value. */
2783 tree
2784 ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *agg,
2785 HOST_WIDE_INT offset, bool by_ref)
2787 struct ipa_agg_jf_item *item;
2788 int i;
2790 if (by_ref != agg->by_ref)
2791 return NULL;
2793 FOR_EACH_VEC_SAFE_ELT (agg->items, i, item)
2794 if (item->offset == offset)
2796 /* Currently we do not have clobber values, return NULL for them once
2797 we do. */
2798 gcc_checking_assert (is_gimple_ip_invariant (item->value));
2799 return item->value;
2801 return NULL;
2804 /* Remove a reference to SYMBOL from the list of references of a node given by
2805 reference description RDESC. Return true if the reference has been
2806 successfully found and removed. */
2808 static bool
2809 remove_described_reference (symtab_node *symbol, struct ipa_cst_ref_desc *rdesc)
2811 struct ipa_ref *to_del;
2812 struct cgraph_edge *origin;
2814 origin = rdesc->cs;
2815 if (!origin)
2816 return false;
2817 to_del = origin->caller->find_reference (symbol, origin->call_stmt,
2818 origin->lto_stmt_uid);
2819 if (!to_del)
2820 return false;
2822 to_del->remove_reference ();
2823 if (dump_file)
2824 fprintf (dump_file, "ipa-prop: Removed a reference from %s/%i to %s.\n",
2825 xstrdup_for_dump (origin->caller->name ()),
2826 origin->caller->order, xstrdup_for_dump (symbol->name ()));
2827 return true;
2830 /* If JFUNC has a reference description with refcount different from
2831 IPA_UNDESCRIBED_USE, return the reference description, otherwise return
2832 NULL. JFUNC must be a constant jump function. */
2834 static struct ipa_cst_ref_desc *
2835 jfunc_rdesc_usable (struct ipa_jump_func *jfunc)
2837 struct ipa_cst_ref_desc *rdesc = ipa_get_jf_constant_rdesc (jfunc);
2838 if (rdesc && rdesc->refcount != IPA_UNDESCRIBED_USE)
2839 return rdesc;
2840 else
2841 return NULL;
2844 /* If the value of constant jump function JFUNC is an address of a function
2845 declaration, return the associated call graph node. Otherwise return
2846 NULL. */
2848 static cgraph_node *
2849 cgraph_node_for_jfunc (struct ipa_jump_func *jfunc)
2851 gcc_checking_assert (jfunc->type == IPA_JF_CONST);
2852 tree cst = ipa_get_jf_constant (jfunc);
2853 if (TREE_CODE (cst) != ADDR_EXPR
2854 || TREE_CODE (TREE_OPERAND (cst, 0)) != FUNCTION_DECL)
2855 return NULL;
2857 return cgraph_node::get (TREE_OPERAND (cst, 0));
2861 /* If JFUNC is a constant jump function with a usable rdesc, decrement its
2862 refcount and if it hits zero, remove reference to SYMBOL from the caller of
2863 the edge specified in the rdesc. Return false if either the symbol or the
2864 reference could not be found, otherwise return true. */
2866 static bool
2867 try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc)
2869 struct ipa_cst_ref_desc *rdesc;
2870 if (jfunc->type == IPA_JF_CONST
2871 && (rdesc = jfunc_rdesc_usable (jfunc))
2872 && --rdesc->refcount == 0)
2874 symtab_node *symbol = cgraph_node_for_jfunc (jfunc);
2875 if (!symbol)
2876 return false;
2878 return remove_described_reference (symbol, rdesc);
2880 return true;
2883 /* Try to find a destination for indirect edge IE that corresponds to a simple
2884 call or a call of a member function pointer and where the destination is a
2885 pointer formal parameter described by jump function JFUNC. If it can be
2886 determined, return the newly direct edge, otherwise return NULL.
2887 NEW_ROOT_INFO is the node info that JFUNC lattices are relative to. */
2889 static struct cgraph_edge *
2890 try_make_edge_direct_simple_call (struct cgraph_edge *ie,
2891 struct ipa_jump_func *jfunc,
2892 struct ipa_node_params *new_root_info)
2894 struct cgraph_edge *cs;
2895 tree target;
2896 bool agg_contents = ie->indirect_info->agg_contents;
2898 if (ie->indirect_info->agg_contents)
2899 target = ipa_find_agg_cst_for_param (&jfunc->agg,
2900 ie->indirect_info->offset,
2901 ie->indirect_info->by_ref);
2902 else
2903 target = ipa_value_from_jfunc (new_root_info, jfunc);
2904 if (!target)
2905 return NULL;
2906 cs = ipa_make_edge_direct_to_target (ie, target);
2908 if (cs && !agg_contents)
2910 bool ok;
2911 gcc_checking_assert (cs->callee
2912 && (cs != ie
2913 || jfunc->type != IPA_JF_CONST
2914 || !cgraph_node_for_jfunc (jfunc)
2915 || cs->callee == cgraph_node_for_jfunc (jfunc)));
2916 ok = try_decrement_rdesc_refcount (jfunc);
2917 gcc_checking_assert (ok);
2920 return cs;
2923 /* Return the target to be used in cases of impossible devirtualization. IE
2924 and target (the latter can be NULL) are dumped when dumping is enabled. */
2926 tree
2927 ipa_impossible_devirt_target (struct cgraph_edge *ie, tree target)
2929 if (dump_file)
2931 if (target)
2932 fprintf (dump_file,
2933 "Type inconsistent devirtualization: %s/%i->%s\n",
2934 ie->caller->name (), ie->caller->order,
2935 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (target)));
2936 else
2937 fprintf (dump_file,
2938 "No devirtualization target in %s/%i\n",
2939 ie->caller->name (), ie->caller->order);
2941 tree new_target = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
2942 cgraph_node::get_create (new_target);
2943 return new_target;
2946 /* Try to find a destination for indirect edge IE that corresponds to a virtual
2947 call based on a formal parameter which is described by jump function JFUNC
2948 and if it can be determined, make it direct and return the direct edge.
2949 Otherwise, return NULL. CTX describes the polymorphic context that the
2950 parameter the call is based on brings along with it. */
2952 static struct cgraph_edge *
2953 try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
2954 struct ipa_jump_func *jfunc,
2955 struct ipa_polymorphic_call_context ctx)
2957 tree target = NULL;
2958 bool speculative = false;
2960 if (!opt_for_fn (ie->caller->decl, flag_devirtualize))
2961 return NULL;
2963 gcc_assert (!ie->indirect_info->by_ref);
2965 /* Try to do lookup via known virtual table pointer value. */
2966 if (!ie->indirect_info->vptr_changed
2967 || opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively))
2969 tree vtable;
2970 unsigned HOST_WIDE_INT offset;
2971 tree t = ipa_find_agg_cst_for_param (&jfunc->agg,
2972 ie->indirect_info->offset,
2973 true);
2974 if (t && vtable_pointer_value_to_vtable (t, &vtable, &offset))
2976 t = gimple_get_virt_method_for_vtable (ie->indirect_info->otr_token,
2977 vtable, offset);
2978 if (t)
2980 if ((TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE
2981 && DECL_FUNCTION_CODE (t) == BUILT_IN_UNREACHABLE)
2982 || !possible_polymorphic_call_target_p
2983 (ie, cgraph_node::get (t)))
2985 /* Do not speculate builtin_unreachable, it is stupid! */
2986 if (!ie->indirect_info->vptr_changed)
2987 target = ipa_impossible_devirt_target (ie, target);
2989 else
2991 target = t;
2992 speculative = ie->indirect_info->vptr_changed;
2998 ipa_polymorphic_call_context ie_context (ie);
2999 vec <cgraph_node *>targets;
3000 bool final;
3002 ctx.offset_by (ie->indirect_info->offset);
3003 if (ie->indirect_info->vptr_changed)
3004 ctx.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
3005 ie->indirect_info->otr_type);
3006 ctx.combine_with (ie_context, ie->indirect_info->otr_type);
3007 targets = possible_polymorphic_call_targets
3008 (ie->indirect_info->otr_type,
3009 ie->indirect_info->otr_token,
3010 ctx, &final);
3011 if (final && targets.length () <= 1)
3013 speculative = false;
3014 if (targets.length () == 1)
3015 target = targets[0]->decl;
3016 else
3017 target = ipa_impossible_devirt_target (ie, NULL_TREE);
3019 else if (!target && opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively)
3020 && !ie->speculative && ie->maybe_hot_p ())
3022 cgraph_node *n;
3023 n = try_speculative_devirtualization (ie->indirect_info->otr_type,
3024 ie->indirect_info->otr_token,
3025 ie->indirect_info->context);
3026 if (n)
3028 target = n->decl;
3029 speculative = true;
3033 if (target)
3035 if (!possible_polymorphic_call_target_p
3036 (ie, cgraph_node::get_create (target)))
3038 if (speculative)
3039 return NULL;
3040 target = ipa_impossible_devirt_target (ie, target);
3042 return ipa_make_edge_direct_to_target (ie, target, speculative);
3044 else
3045 return NULL;
3048 /* Update the param called notes associated with NODE when CS is being inlined,
3049 assuming NODE is (potentially indirectly) inlined into CS->callee.
3050 Moreover, if the callee is discovered to be constant, create a new cgraph
3051 edge for it. Newly discovered indirect edges will be added to *NEW_EDGES,
3052 unless NEW_EDGES is NULL. Return true iff a new edge(s) were created. */
3054 static bool
3055 update_indirect_edges_after_inlining (struct cgraph_edge *cs,
3056 struct cgraph_node *node,
3057 vec<cgraph_edge *> *new_edges)
3059 struct ipa_edge_args *top;
3060 struct cgraph_edge *ie, *next_ie, *new_direct_edge;
3061 struct ipa_node_params *new_root_info;
3062 bool res = false;
3064 ipa_check_create_edge_args ();
3065 top = IPA_EDGE_REF (cs);
3066 new_root_info = IPA_NODE_REF (cs->caller->global.inlined_to
3067 ? cs->caller->global.inlined_to
3068 : cs->caller);
3070 for (ie = node->indirect_calls; ie; ie = next_ie)
3072 struct cgraph_indirect_call_info *ici = ie->indirect_info;
3073 struct ipa_jump_func *jfunc;
3074 int param_index;
3075 cgraph_node *spec_target = NULL;
3077 next_ie = ie->next_callee;
3079 if (ici->param_index == -1)
3080 continue;
3082 /* We must check range due to calls with variable number of arguments: */
3083 if (ici->param_index >= ipa_get_cs_argument_count (top))
3085 ici->param_index = -1;
3086 continue;
3089 param_index = ici->param_index;
3090 jfunc = ipa_get_ith_jump_func (top, param_index);
3092 if (ie->speculative)
3094 struct cgraph_edge *de;
3095 struct ipa_ref *ref;
3096 ie->speculative_call_info (de, ie, ref);
3097 spec_target = de->callee;
3100 if (!opt_for_fn (node->decl, flag_indirect_inlining))
3101 new_direct_edge = NULL;
3102 else if (ici->polymorphic)
3104 ipa_polymorphic_call_context ctx;
3105 ctx = ipa_context_from_jfunc (new_root_info, cs, param_index, jfunc);
3106 new_direct_edge = try_make_edge_direct_virtual_call (ie, jfunc, ctx);
3108 else
3109 new_direct_edge = try_make_edge_direct_simple_call (ie, jfunc,
3110 new_root_info);
3111 /* If speculation was removed, then we need to do nothing. */
3112 if (new_direct_edge && new_direct_edge != ie
3113 && new_direct_edge->callee == spec_target)
3115 new_direct_edge->indirect_inlining_edge = 1;
3116 top = IPA_EDGE_REF (cs);
3117 res = true;
3118 if (!new_direct_edge->speculative)
3119 continue;
3121 else if (new_direct_edge)
3123 new_direct_edge->indirect_inlining_edge = 1;
3124 if (new_direct_edge->call_stmt)
3125 new_direct_edge->call_stmt_cannot_inline_p
3126 = !gimple_check_call_matching_types (
3127 new_direct_edge->call_stmt,
3128 new_direct_edge->callee->decl, false);
3129 if (new_edges)
3131 new_edges->safe_push (new_direct_edge);
3132 res = true;
3134 top = IPA_EDGE_REF (cs);
3135 /* If speculative edge was introduced we still need to update
3136 call info of the indirect edge. */
3137 if (!new_direct_edge->speculative)
3138 continue;
3140 if (jfunc->type == IPA_JF_PASS_THROUGH
3141 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
3143 if (ici->agg_contents
3144 && !ipa_get_jf_pass_through_agg_preserved (jfunc)
3145 && !ici->polymorphic)
3146 ici->param_index = -1;
3147 else
3149 ici->param_index = ipa_get_jf_pass_through_formal_id (jfunc);
3150 if (ici->polymorphic
3151 && !ipa_get_jf_pass_through_type_preserved (jfunc))
3152 ici->vptr_changed = true;
3155 else if (jfunc->type == IPA_JF_ANCESTOR)
3157 if (ici->agg_contents
3158 && !ipa_get_jf_ancestor_agg_preserved (jfunc)
3159 && !ici->polymorphic)
3160 ici->param_index = -1;
3161 else
3163 ici->param_index = ipa_get_jf_ancestor_formal_id (jfunc);
3164 ici->offset += ipa_get_jf_ancestor_offset (jfunc);
3165 if (ici->polymorphic
3166 && !ipa_get_jf_ancestor_type_preserved (jfunc))
3167 ici->vptr_changed = true;
3170 else
3171 /* Either we can find a destination for this edge now or never. */
3172 ici->param_index = -1;
3175 return res;
3178 /* Recursively traverse subtree of NODE (including node) made of inlined
3179 cgraph_edges when CS has been inlined and invoke
3180 update_indirect_edges_after_inlining on all nodes and
3181 update_jump_functions_after_inlining on all non-inlined edges that lead out
3182 of this subtree. Newly discovered indirect edges will be added to
3183 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were
3184 created. */
3186 static bool
3187 propagate_info_to_inlined_callees (struct cgraph_edge *cs,
3188 struct cgraph_node *node,
3189 vec<cgraph_edge *> *new_edges)
3191 struct cgraph_edge *e;
3192 bool res;
3194 res = update_indirect_edges_after_inlining (cs, node, new_edges);
3196 for (e = node->callees; e; e = e->next_callee)
3197 if (!e->inline_failed)
3198 res |= propagate_info_to_inlined_callees (cs, e->callee, new_edges);
3199 else
3200 update_jump_functions_after_inlining (cs, e);
3201 for (e = node->indirect_calls; e; e = e->next_callee)
3202 update_jump_functions_after_inlining (cs, e);
3204 return res;
3207 /* Combine two controlled uses counts as done during inlining. */
3209 static int
3210 combine_controlled_uses_counters (int c, int d)
3212 if (c == IPA_UNDESCRIBED_USE || d == IPA_UNDESCRIBED_USE)
3213 return IPA_UNDESCRIBED_USE;
3214 else
3215 return c + d - 1;
3218 /* Propagate number of controlled users from CS->caleee to the new root of the
3219 tree of inlined nodes. */
3221 static void
3222 propagate_controlled_uses (struct cgraph_edge *cs)
3224 struct ipa_edge_args *args = IPA_EDGE_REF (cs);
3225 struct cgraph_node *new_root = cs->caller->global.inlined_to
3226 ? cs->caller->global.inlined_to : cs->caller;
3227 struct ipa_node_params *new_root_info = IPA_NODE_REF (new_root);
3228 struct ipa_node_params *old_root_info = IPA_NODE_REF (cs->callee);
3229 int count, i;
3231 count = MIN (ipa_get_cs_argument_count (args),
3232 ipa_get_param_count (old_root_info));
3233 for (i = 0; i < count; i++)
3235 struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
3236 struct ipa_cst_ref_desc *rdesc;
3238 if (jf->type == IPA_JF_PASS_THROUGH)
3240 int src_idx, c, d;
3241 src_idx = ipa_get_jf_pass_through_formal_id (jf);
3242 c = ipa_get_controlled_uses (new_root_info, src_idx);
3243 d = ipa_get_controlled_uses (old_root_info, i);
3245 gcc_checking_assert (ipa_get_jf_pass_through_operation (jf)
3246 == NOP_EXPR || c == IPA_UNDESCRIBED_USE);
3247 c = combine_controlled_uses_counters (c, d);
3248 ipa_set_controlled_uses (new_root_info, src_idx, c);
3249 if (c == 0 && new_root_info->ipcp_orig_node)
3251 struct cgraph_node *n;
3252 struct ipa_ref *ref;
3253 tree t = new_root_info->known_csts[src_idx];
3255 if (t && TREE_CODE (t) == ADDR_EXPR
3256 && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
3257 && (n = cgraph_node::get (TREE_OPERAND (t, 0)))
3258 && (ref = new_root->find_reference (n, NULL, 0)))
3260 if (dump_file)
3261 fprintf (dump_file, "ipa-prop: Removing cloning-created "
3262 "reference from %s/%i to %s/%i.\n",
3263 xstrdup_for_dump (new_root->name ()),
3264 new_root->order,
3265 xstrdup_for_dump (n->name ()), n->order);
3266 ref->remove_reference ();
3270 else if (jf->type == IPA_JF_CONST
3271 && (rdesc = jfunc_rdesc_usable (jf)))
3273 int d = ipa_get_controlled_uses (old_root_info, i);
3274 int c = rdesc->refcount;
3275 rdesc->refcount = combine_controlled_uses_counters (c, d);
3276 if (rdesc->refcount == 0)
3278 tree cst = ipa_get_jf_constant (jf);
3279 struct cgraph_node *n;
3280 gcc_checking_assert (TREE_CODE (cst) == ADDR_EXPR
3281 && TREE_CODE (TREE_OPERAND (cst, 0))
3282 == FUNCTION_DECL);
3283 n = cgraph_node::get (TREE_OPERAND (cst, 0));
3284 if (n)
3286 struct cgraph_node *clone;
3287 bool ok;
3288 ok = remove_described_reference (n, rdesc);
3289 gcc_checking_assert (ok);
3291 clone = cs->caller;
3292 while (clone->global.inlined_to
3293 && clone != rdesc->cs->caller
3294 && IPA_NODE_REF (clone)->ipcp_orig_node)
3296 struct ipa_ref *ref;
3297 ref = clone->find_reference (n, NULL, 0);
3298 if (ref)
3300 if (dump_file)
3301 fprintf (dump_file, "ipa-prop: Removing "
3302 "cloning-created reference "
3303 "from %s/%i to %s/%i.\n",
3304 xstrdup_for_dump (clone->name ()),
3305 clone->order,
3306 xstrdup_for_dump (n->name ()),
3307 n->order);
3308 ref->remove_reference ();
3310 clone = clone->callers->caller;
3317 for (i = ipa_get_param_count (old_root_info);
3318 i < ipa_get_cs_argument_count (args);
3319 i++)
3321 struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
3323 if (jf->type == IPA_JF_CONST)
3325 struct ipa_cst_ref_desc *rdesc = jfunc_rdesc_usable (jf);
3326 if (rdesc)
3327 rdesc->refcount = IPA_UNDESCRIBED_USE;
3329 else if (jf->type == IPA_JF_PASS_THROUGH)
3330 ipa_set_controlled_uses (new_root_info,
3331 jf->value.pass_through.formal_id,
3332 IPA_UNDESCRIBED_USE);
3336 /* Update jump functions and call note functions on inlining the call site CS.
3337 CS is expected to lead to a node already cloned by
3338 cgraph_clone_inline_nodes. Newly discovered indirect edges will be added to
3339 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were +
3340 created. */
3342 bool
3343 ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
3344 vec<cgraph_edge *> *new_edges)
3346 bool changed;
3347 /* Do nothing if the preparation phase has not been carried out yet
3348 (i.e. during early inlining). */
3349 if (!ipa_node_params_sum)
3350 return false;
3351 gcc_assert (ipa_edge_args_vector);
3353 propagate_controlled_uses (cs);
3354 changed = propagate_info_to_inlined_callees (cs, cs->callee, new_edges);
3356 return changed;
3359 /* Frees all dynamically allocated structures that the argument info points
3360 to. */
3362 void
3363 ipa_free_edge_args_substructures (struct ipa_edge_args *args)
3365 vec_free (args->jump_functions);
3366 memset (args, 0, sizeof (*args));
3369 /* Free all ipa_edge structures. */
3371 void
3372 ipa_free_all_edge_args (void)
3374 int i;
3375 struct ipa_edge_args *args;
3377 if (!ipa_edge_args_vector)
3378 return;
3380 FOR_EACH_VEC_ELT (*ipa_edge_args_vector, i, args)
3381 ipa_free_edge_args_substructures (args);
3383 vec_free (ipa_edge_args_vector);
3386 /* Frees all dynamically allocated structures that the param info points
3387 to. */
3389 ipa_node_params::~ipa_node_params ()
3391 descriptors.release ();
3392 free (lattices);
3393 /* Lattice values and their sources are deallocated with their alocation
3394 pool. */
3395 known_contexts.release ();
3397 lattices = NULL;
3398 ipcp_orig_node = NULL;
3399 analysis_done = 0;
3400 node_enqueued = 0;
3401 do_clone_for_all_contexts = 0;
3402 is_all_contexts_clone = 0;
3403 node_dead = 0;
3406 /* Free all ipa_node_params structures. */
3408 void
3409 ipa_free_all_node_params (void)
3411 delete ipa_node_params_sum;
3412 ipa_node_params_sum = NULL;
3415 /* Grow ipcp_transformations if necessary. */
3417 void
3418 ipcp_grow_transformations_if_necessary (void)
3420 if (vec_safe_length (ipcp_transformations)
3421 <= (unsigned) symtab->cgraph_max_uid)
3422 vec_safe_grow_cleared (ipcp_transformations, symtab->cgraph_max_uid + 1);
3425 /* Set the aggregate replacements of NODE to be AGGVALS. */
3427 void
3428 ipa_set_node_agg_value_chain (struct cgraph_node *node,
3429 struct ipa_agg_replacement_value *aggvals)
3431 ipcp_grow_transformations_if_necessary ();
3432 (*ipcp_transformations)[node->uid].agg_values = aggvals;
3435 /* Hook that is called by cgraph.c when an edge is removed. */
3437 static void
3438 ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
3440 struct ipa_edge_args *args;
3442 /* During IPA-CP updating we can be called on not-yet analyzed clones. */
3443 if (vec_safe_length (ipa_edge_args_vector) <= (unsigned)cs->uid)
3444 return;
3446 args = IPA_EDGE_REF (cs);
3447 if (args->jump_functions)
3449 struct ipa_jump_func *jf;
3450 int i;
3451 FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
3453 struct ipa_cst_ref_desc *rdesc;
3454 try_decrement_rdesc_refcount (jf);
3455 if (jf->type == IPA_JF_CONST
3456 && (rdesc = ipa_get_jf_constant_rdesc (jf))
3457 && rdesc->cs == cs)
3458 rdesc->cs = NULL;
3462 ipa_free_edge_args_substructures (IPA_EDGE_REF (cs));
3465 /* Hook that is called by cgraph.c when an edge is duplicated. */
3467 static void
3468 ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
3469 void *)
3471 struct ipa_edge_args *old_args, *new_args;
3472 unsigned int i;
3474 ipa_check_create_edge_args ();
3476 old_args = IPA_EDGE_REF (src);
3477 new_args = IPA_EDGE_REF (dst);
3479 new_args->jump_functions = vec_safe_copy (old_args->jump_functions);
3480 if (old_args->polymorphic_call_contexts)
3481 new_args->polymorphic_call_contexts
3482 = vec_safe_copy (old_args->polymorphic_call_contexts);
3484 for (i = 0; i < vec_safe_length (old_args->jump_functions); i++)
3486 struct ipa_jump_func *src_jf = ipa_get_ith_jump_func (old_args, i);
3487 struct ipa_jump_func *dst_jf = ipa_get_ith_jump_func (new_args, i);
3489 dst_jf->agg.items = vec_safe_copy (dst_jf->agg.items);
3491 if (src_jf->type == IPA_JF_CONST)
3493 struct ipa_cst_ref_desc *src_rdesc = jfunc_rdesc_usable (src_jf);
3495 if (!src_rdesc)
3496 dst_jf->value.constant.rdesc = NULL;
3497 else if (src->caller == dst->caller)
3499 struct ipa_ref *ref;
3500 symtab_node *n = cgraph_node_for_jfunc (src_jf);
3501 gcc_checking_assert (n);
3502 ref = src->caller->find_reference (n, src->call_stmt,
3503 src->lto_stmt_uid);
3504 gcc_checking_assert (ref);
3505 dst->caller->clone_reference (ref, ref->stmt);
3507 struct ipa_cst_ref_desc *dst_rdesc = ipa_refdesc_pool.allocate ();
3508 dst_rdesc->cs = dst;
3509 dst_rdesc->refcount = src_rdesc->refcount;
3510 dst_rdesc->next_duplicate = NULL;
3511 dst_jf->value.constant.rdesc = dst_rdesc;
3513 else if (src_rdesc->cs == src)
3515 struct ipa_cst_ref_desc *dst_rdesc = ipa_refdesc_pool.allocate ();
3516 dst_rdesc->cs = dst;
3517 dst_rdesc->refcount = src_rdesc->refcount;
3518 dst_rdesc->next_duplicate = src_rdesc->next_duplicate;
3519 src_rdesc->next_duplicate = dst_rdesc;
3520 dst_jf->value.constant.rdesc = dst_rdesc;
3522 else
3524 struct ipa_cst_ref_desc *dst_rdesc;
3525 /* This can happen during inlining, when a JFUNC can refer to a
3526 reference taken in a function up in the tree of inline clones.
3527 We need to find the duplicate that refers to our tree of
3528 inline clones. */
3530 gcc_assert (dst->caller->global.inlined_to);
3531 for (dst_rdesc = src_rdesc->next_duplicate;
3532 dst_rdesc;
3533 dst_rdesc = dst_rdesc->next_duplicate)
3535 struct cgraph_node *top;
3536 top = dst_rdesc->cs->caller->global.inlined_to
3537 ? dst_rdesc->cs->caller->global.inlined_to
3538 : dst_rdesc->cs->caller;
3539 if (dst->caller->global.inlined_to == top)
3540 break;
3542 gcc_assert (dst_rdesc);
3543 dst_jf->value.constant.rdesc = dst_rdesc;
3546 else if (dst_jf->type == IPA_JF_PASS_THROUGH
3547 && src->caller == dst->caller)
3549 struct cgraph_node *inline_root = dst->caller->global.inlined_to
3550 ? dst->caller->global.inlined_to : dst->caller;
3551 struct ipa_node_params *root_info = IPA_NODE_REF (inline_root);
3552 int idx = ipa_get_jf_pass_through_formal_id (dst_jf);
3554 int c = ipa_get_controlled_uses (root_info, idx);
3555 if (c != IPA_UNDESCRIBED_USE)
3557 c++;
3558 ipa_set_controlled_uses (root_info, idx, c);
3564 /* Analyze newly added function into callgraph. */
3566 static void
3567 ipa_add_new_function (cgraph_node *node, void *data ATTRIBUTE_UNUSED)
3569 if (node->has_gimple_body_p ())
3570 ipa_analyze_node (node);
3573 /* Hook that is called by summary when a node is duplicated. */
3575 void
3576 ipa_node_params_t::duplicate(cgraph_node *src, cgraph_node *dst,
3577 ipa_node_params *old_info,
3578 ipa_node_params *new_info)
3580 ipa_agg_replacement_value *old_av, *new_av;
3582 new_info->descriptors = old_info->descriptors.copy ();
3583 new_info->lattices = NULL;
3584 new_info->ipcp_orig_node = old_info->ipcp_orig_node;
3586 new_info->analysis_done = old_info->analysis_done;
3587 new_info->node_enqueued = old_info->node_enqueued;
3589 old_av = ipa_get_agg_replacements_for_node (src);
3590 if (old_av)
3592 new_av = NULL;
3593 while (old_av)
3595 struct ipa_agg_replacement_value *v;
3597 v = ggc_alloc<ipa_agg_replacement_value> ();
3598 memcpy (v, old_av, sizeof (*v));
3599 v->next = new_av;
3600 new_av = v;
3601 old_av = old_av->next;
3603 ipa_set_node_agg_value_chain (dst, new_av);
3606 ipcp_transformation_summary *src_trans = ipcp_get_transformation_summary (src);
3608 if (src_trans && vec_safe_length (src_trans->alignments) > 0)
3610 ipcp_grow_transformations_if_necessary ();
3611 src_trans = ipcp_get_transformation_summary (src);
3612 const vec<ipa_alignment, va_gc> *src_alignments = src_trans->alignments;
3613 vec<ipa_alignment, va_gc> *&dst_alignments
3614 = ipcp_get_transformation_summary (dst)->alignments;
3615 vec_safe_reserve_exact (dst_alignments, src_alignments->length ());
3616 for (unsigned i = 0; i < src_alignments->length (); ++i)
3617 dst_alignments->quick_push ((*src_alignments)[i]);
3621 /* Register our cgraph hooks if they are not already there. */
3623 void
3624 ipa_register_cgraph_hooks (void)
3626 ipa_check_create_node_params ();
3628 if (!edge_removal_hook_holder)
3629 edge_removal_hook_holder =
3630 symtab->add_edge_removal_hook (&ipa_edge_removal_hook, NULL);
3631 if (!edge_duplication_hook_holder)
3632 edge_duplication_hook_holder =
3633 symtab->add_edge_duplication_hook (&ipa_edge_duplication_hook, NULL);
3634 function_insertion_hook_holder =
3635 symtab->add_cgraph_insertion_hook (&ipa_add_new_function, NULL);
3638 /* Unregister our cgraph hooks if they are not already there. */
3640 static void
3641 ipa_unregister_cgraph_hooks (void)
3643 symtab->remove_edge_removal_hook (edge_removal_hook_holder);
3644 edge_removal_hook_holder = NULL;
3645 symtab->remove_edge_duplication_hook (edge_duplication_hook_holder);
3646 edge_duplication_hook_holder = NULL;
3647 symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
3648 function_insertion_hook_holder = NULL;
3651 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
3652 longer needed after ipa-cp. */
3654 void
3655 ipa_free_all_structures_after_ipa_cp (void)
3657 if (!optimize && !in_lto_p)
3659 ipa_free_all_edge_args ();
3660 ipa_free_all_node_params ();
3661 ipcp_sources_pool.release ();
3662 ipcp_cst_values_pool.release ();
3663 ipcp_poly_ctx_values_pool.release ();
3664 ipcp_agg_lattice_pool.release ();
3665 ipa_unregister_cgraph_hooks ();
3666 ipa_refdesc_pool.release ();
3670 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
3671 longer needed after indirect inlining. */
3673 void
3674 ipa_free_all_structures_after_iinln (void)
3676 ipa_free_all_edge_args ();
3677 ipa_free_all_node_params ();
3678 ipa_unregister_cgraph_hooks ();
3679 ipcp_sources_pool.release ();
3680 ipcp_cst_values_pool.release ();
3681 ipcp_poly_ctx_values_pool.release ();
3682 ipcp_agg_lattice_pool.release ();
3683 ipa_refdesc_pool.release ();
3686 /* Print ipa_tree_map data structures of all functions in the
3687 callgraph to F. */
3689 void
3690 ipa_print_node_params (FILE *f, struct cgraph_node *node)
3692 int i, count;
3693 struct ipa_node_params *info;
3695 if (!node->definition)
3696 return;
3697 info = IPA_NODE_REF (node);
3698 fprintf (f, " function %s/%i parameter descriptors:\n",
3699 node->name (), node->order);
3700 count = ipa_get_param_count (info);
3701 for (i = 0; i < count; i++)
3703 int c;
3705 fprintf (f, " ");
3706 ipa_dump_param (f, info, i);
3707 if (ipa_is_param_used (info, i))
3708 fprintf (f, " used");
3709 c = ipa_get_controlled_uses (info, i);
3710 if (c == IPA_UNDESCRIBED_USE)
3711 fprintf (f, " undescribed_use");
3712 else
3713 fprintf (f, " controlled_uses=%i", c);
3714 fprintf (f, "\n");
3718 /* Print ipa_tree_map data structures of all functions in the
3719 callgraph to F. */
3721 void
3722 ipa_print_all_params (FILE * f)
3724 struct cgraph_node *node;
3726 fprintf (f, "\nFunction parameters:\n");
3727 FOR_EACH_FUNCTION (node)
3728 ipa_print_node_params (f, node);
3731 /* Return a heap allocated vector containing formal parameters of FNDECL. */
3733 vec<tree>
3734 ipa_get_vector_of_formal_parms (tree fndecl)
3736 vec<tree> args;
3737 int count;
3738 tree parm;
3740 gcc_assert (!flag_wpa);
3741 count = count_formal_params (fndecl);
3742 args.create (count);
3743 for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
3744 args.quick_push (parm);
3746 return args;
3749 /* Return a heap allocated vector containing types of formal parameters of
3750 function type FNTYPE. */
3752 vec<tree>
3753 ipa_get_vector_of_formal_parm_types (tree fntype)
3755 vec<tree> types;
3756 int count = 0;
3757 tree t;
3759 for (t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t))
3760 count++;
3762 types.create (count);
3763 for (t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t))
3764 types.quick_push (TREE_VALUE (t));
3766 return types;
3769 /* Modify the function declaration FNDECL and its type according to the plan in
3770 ADJUSTMENTS. It also sets base fields of individual adjustments structures
3771 to reflect the actual parameters being modified which are determined by the
3772 base_index field. */
3774 void
3775 ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments)
3777 vec<tree> oparms = ipa_get_vector_of_formal_parms (fndecl);
3778 tree orig_type = TREE_TYPE (fndecl);
3779 tree old_arg_types = TYPE_ARG_TYPES (orig_type);
3781 /* The following test is an ugly hack, some functions simply don't have any
3782 arguments in their type. This is probably a bug but well... */
3783 bool care_for_types = (old_arg_types != NULL_TREE);
3784 bool last_parm_void;
3785 vec<tree> otypes;
3786 if (care_for_types)
3788 last_parm_void = (TREE_VALUE (tree_last (old_arg_types))
3789 == void_type_node);
3790 otypes = ipa_get_vector_of_formal_parm_types (orig_type);
3791 if (last_parm_void)
3792 gcc_assert (oparms.length () + 1 == otypes.length ());
3793 else
3794 gcc_assert (oparms.length () == otypes.length ());
3796 else
3798 last_parm_void = false;
3799 otypes.create (0);
3802 int len = adjustments.length ();
3803 tree *link = &DECL_ARGUMENTS (fndecl);
3804 tree new_arg_types = NULL;
3805 for (int i = 0; i < len; i++)
3807 struct ipa_parm_adjustment *adj;
3808 gcc_assert (link);
3810 adj = &adjustments[i];
3811 tree parm;
3812 if (adj->op == IPA_PARM_OP_NEW)
3813 parm = NULL;
3814 else
3815 parm = oparms[adj->base_index];
3816 adj->base = parm;
3818 if (adj->op == IPA_PARM_OP_COPY)
3820 if (care_for_types)
3821 new_arg_types = tree_cons (NULL_TREE, otypes[adj->base_index],
3822 new_arg_types);
3823 *link = parm;
3824 link = &DECL_CHAIN (parm);
3826 else if (adj->op != IPA_PARM_OP_REMOVE)
3828 tree new_parm;
3829 tree ptype;
3831 if (adj->by_ref)
3832 ptype = build_pointer_type (adj->type);
3833 else
3835 ptype = adj->type;
3836 if (is_gimple_reg_type (ptype))
3838 unsigned malign = GET_MODE_ALIGNMENT (TYPE_MODE (ptype));
3839 if (TYPE_ALIGN (ptype) < malign)
3840 ptype = build_aligned_type (ptype, malign);
3844 if (care_for_types)
3845 new_arg_types = tree_cons (NULL_TREE, ptype, new_arg_types);
3847 new_parm = build_decl (UNKNOWN_LOCATION, PARM_DECL, NULL_TREE,
3848 ptype);
3849 const char *prefix = adj->arg_prefix ? adj->arg_prefix : "SYNTH";
3850 DECL_NAME (new_parm) = create_tmp_var_name (prefix);
3851 DECL_ARTIFICIAL (new_parm) = 1;
3852 DECL_ARG_TYPE (new_parm) = ptype;
3853 DECL_CONTEXT (new_parm) = fndecl;
3854 TREE_USED (new_parm) = 1;
3855 DECL_IGNORED_P (new_parm) = 1;
3856 layout_decl (new_parm, 0);
3858 if (adj->op == IPA_PARM_OP_NEW)
3859 adj->base = NULL;
3860 else
3861 adj->base = parm;
3862 adj->new_decl = new_parm;
3864 *link = new_parm;
3865 link = &DECL_CHAIN (new_parm);
3869 *link = NULL_TREE;
3871 tree new_reversed = NULL;
3872 if (care_for_types)
3874 new_reversed = nreverse (new_arg_types);
3875 if (last_parm_void)
3877 if (new_reversed)
3878 TREE_CHAIN (new_arg_types) = void_list_node;
3879 else
3880 new_reversed = void_list_node;
3884 /* Use copy_node to preserve as much as possible from original type
3885 (debug info, attribute lists etc.)
3886 Exception is METHOD_TYPEs must have THIS argument.
3887 When we are asked to remove it, we need to build new FUNCTION_TYPE
3888 instead. */
3889 tree new_type = NULL;
3890 if (TREE_CODE (orig_type) != METHOD_TYPE
3891 || (adjustments[0].op == IPA_PARM_OP_COPY
3892 && adjustments[0].base_index == 0))
3894 new_type = build_distinct_type_copy (orig_type);
3895 TYPE_ARG_TYPES (new_type) = new_reversed;
3897 else
3899 new_type
3900 = build_distinct_type_copy (build_function_type (TREE_TYPE (orig_type),
3901 new_reversed));
3902 TYPE_CONTEXT (new_type) = TYPE_CONTEXT (orig_type);
3903 DECL_VINDEX (fndecl) = NULL_TREE;
3906 /* When signature changes, we need to clear builtin info. */
3907 if (DECL_BUILT_IN (fndecl))
3909 DECL_BUILT_IN_CLASS (fndecl) = NOT_BUILT_IN;
3910 DECL_FUNCTION_CODE (fndecl) = (enum built_in_function) 0;
3913 TREE_TYPE (fndecl) = new_type;
3914 DECL_VIRTUAL_P (fndecl) = 0;
3915 DECL_LANG_SPECIFIC (fndecl) = NULL;
3916 otypes.release ();
3917 oparms.release ();
3920 /* Modify actual arguments of a function call CS as indicated in ADJUSTMENTS.
3921 If this is a directly recursive call, CS must be NULL. Otherwise it must
3922 contain the corresponding call graph edge. */
3924 void
3925 ipa_modify_call_arguments (struct cgraph_edge *cs, gcall *stmt,
3926 ipa_parm_adjustment_vec adjustments)
3928 struct cgraph_node *current_node = cgraph_node::get (current_function_decl);
3929 vec<tree> vargs;
3930 vec<tree, va_gc> **debug_args = NULL;
3931 gcall *new_stmt;
3932 gimple_stmt_iterator gsi, prev_gsi;
3933 tree callee_decl;
3934 int i, len;
3936 len = adjustments.length ();
3937 vargs.create (len);
3938 callee_decl = !cs ? gimple_call_fndecl (stmt) : cs->callee->decl;
3939 current_node->remove_stmt_references (stmt);
3941 gsi = gsi_for_stmt (stmt);
3942 prev_gsi = gsi;
3943 gsi_prev (&prev_gsi);
3944 for (i = 0; i < len; i++)
3946 struct ipa_parm_adjustment *adj;
3948 adj = &adjustments[i];
3950 if (adj->op == IPA_PARM_OP_COPY)
3952 tree arg = gimple_call_arg (stmt, adj->base_index);
3954 vargs.quick_push (arg);
3956 else if (adj->op != IPA_PARM_OP_REMOVE)
3958 tree expr, base, off;
3959 location_t loc;
3960 unsigned int deref_align = 0;
3961 bool deref_base = false;
3963 /* We create a new parameter out of the value of the old one, we can
3964 do the following kind of transformations:
3966 - A scalar passed by reference is converted to a scalar passed by
3967 value. (adj->by_ref is false and the type of the original
3968 actual argument is a pointer to a scalar).
3970 - A part of an aggregate is passed instead of the whole aggregate.
3971 The part can be passed either by value or by reference, this is
3972 determined by value of adj->by_ref. Moreover, the code below
3973 handles both situations when the original aggregate is passed by
3974 value (its type is not a pointer) and when it is passed by
3975 reference (it is a pointer to an aggregate).
3977 When the new argument is passed by reference (adj->by_ref is true)
3978 it must be a part of an aggregate and therefore we form it by
3979 simply taking the address of a reference inside the original
3980 aggregate. */
3982 gcc_checking_assert (adj->offset % BITS_PER_UNIT == 0);
3983 base = gimple_call_arg (stmt, adj->base_index);
3984 loc = DECL_P (base) ? DECL_SOURCE_LOCATION (base)
3985 : EXPR_LOCATION (base);
3987 if (TREE_CODE (base) != ADDR_EXPR
3988 && POINTER_TYPE_P (TREE_TYPE (base)))
3989 off = build_int_cst (adj->alias_ptr_type,
3990 adj->offset / BITS_PER_UNIT);
3991 else
3993 HOST_WIDE_INT base_offset;
3994 tree prev_base;
3995 bool addrof;
3997 if (TREE_CODE (base) == ADDR_EXPR)
3999 base = TREE_OPERAND (base, 0);
4000 addrof = true;
4002 else
4003 addrof = false;
4004 prev_base = base;
4005 base = get_addr_base_and_unit_offset (base, &base_offset);
4006 /* Aggregate arguments can have non-invariant addresses. */
4007 if (!base)
4009 base = build_fold_addr_expr (prev_base);
4010 off = build_int_cst (adj->alias_ptr_type,
4011 adj->offset / BITS_PER_UNIT);
4013 else if (TREE_CODE (base) == MEM_REF)
4015 if (!addrof)
4017 deref_base = true;
4018 deref_align = TYPE_ALIGN (TREE_TYPE (base));
4020 off = build_int_cst (adj->alias_ptr_type,
4021 base_offset
4022 + adj->offset / BITS_PER_UNIT);
4023 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1),
4024 off);
4025 base = TREE_OPERAND (base, 0);
4027 else
4029 off = build_int_cst (adj->alias_ptr_type,
4030 base_offset
4031 + adj->offset / BITS_PER_UNIT);
4032 base = build_fold_addr_expr (base);
4036 if (!adj->by_ref)
4038 tree type = adj->type;
4039 unsigned int align;
4040 unsigned HOST_WIDE_INT misalign;
4042 if (deref_base)
4044 align = deref_align;
4045 misalign = 0;
4047 else
4049 get_pointer_alignment_1 (base, &align, &misalign);
4050 if (TYPE_ALIGN (type) > align)
4051 align = TYPE_ALIGN (type);
4053 misalign += (offset_int::from (off, SIGNED).to_short_addr ()
4054 * BITS_PER_UNIT);
4055 misalign = misalign & (align - 1);
4056 if (misalign != 0)
4057 align = (misalign & -misalign);
4058 if (align < TYPE_ALIGN (type))
4059 type = build_aligned_type (type, align);
4060 base = force_gimple_operand_gsi (&gsi, base,
4061 true, NULL, true, GSI_SAME_STMT);
4062 expr = fold_build2_loc (loc, MEM_REF, type, base, off);
4063 /* If expr is not a valid gimple call argument emit
4064 a load into a temporary. */
4065 if (is_gimple_reg_type (TREE_TYPE (expr)))
4067 gimple tem = gimple_build_assign (NULL_TREE, expr);
4068 if (gimple_in_ssa_p (cfun))
4070 gimple_set_vuse (tem, gimple_vuse (stmt));
4071 expr = make_ssa_name (TREE_TYPE (expr), tem);
4073 else
4074 expr = create_tmp_reg (TREE_TYPE (expr));
4075 gimple_assign_set_lhs (tem, expr);
4076 gsi_insert_before (&gsi, tem, GSI_SAME_STMT);
4079 else
4081 expr = fold_build2_loc (loc, MEM_REF, adj->type, base, off);
4082 expr = build_fold_addr_expr (expr);
4083 expr = force_gimple_operand_gsi (&gsi, expr,
4084 true, NULL, true, GSI_SAME_STMT);
4086 vargs.quick_push (expr);
4088 if (adj->op != IPA_PARM_OP_COPY && MAY_HAVE_DEBUG_STMTS)
4090 unsigned int ix;
4091 tree ddecl = NULL_TREE, origin = DECL_ORIGIN (adj->base), arg;
4092 gimple def_temp;
4094 arg = gimple_call_arg (stmt, adj->base_index);
4095 if (!useless_type_conversion_p (TREE_TYPE (origin), TREE_TYPE (arg)))
4097 if (!fold_convertible_p (TREE_TYPE (origin), arg))
4098 continue;
4099 arg = fold_convert_loc (gimple_location (stmt),
4100 TREE_TYPE (origin), arg);
4102 if (debug_args == NULL)
4103 debug_args = decl_debug_args_insert (callee_decl);
4104 for (ix = 0; vec_safe_iterate (*debug_args, ix, &ddecl); ix += 2)
4105 if (ddecl == origin)
4107 ddecl = (**debug_args)[ix + 1];
4108 break;
4110 if (ddecl == NULL)
4112 ddecl = make_node (DEBUG_EXPR_DECL);
4113 DECL_ARTIFICIAL (ddecl) = 1;
4114 TREE_TYPE (ddecl) = TREE_TYPE (origin);
4115 DECL_MODE (ddecl) = DECL_MODE (origin);
4117 vec_safe_push (*debug_args, origin);
4118 vec_safe_push (*debug_args, ddecl);
4120 def_temp = gimple_build_debug_bind (ddecl, unshare_expr (arg), stmt);
4121 gsi_insert_before (&gsi, def_temp, GSI_SAME_STMT);
4125 if (dump_file && (dump_flags & TDF_DETAILS))
4127 fprintf (dump_file, "replacing stmt:");
4128 print_gimple_stmt (dump_file, gsi_stmt (gsi), 0, 0);
4131 new_stmt = gimple_build_call_vec (callee_decl, vargs);
4132 vargs.release ();
4133 if (gimple_call_lhs (stmt))
4134 gimple_call_set_lhs (new_stmt, gimple_call_lhs (stmt));
4136 gimple_set_block (new_stmt, gimple_block (stmt));
4137 if (gimple_has_location (stmt))
4138 gimple_set_location (new_stmt, gimple_location (stmt));
4139 gimple_call_set_chain (new_stmt, gimple_call_chain (stmt));
4140 gimple_call_copy_flags (new_stmt, stmt);
4141 if (gimple_in_ssa_p (cfun))
4143 gimple_set_vuse (new_stmt, gimple_vuse (stmt));
4144 if (gimple_vdef (stmt))
4146 gimple_set_vdef (new_stmt, gimple_vdef (stmt));
4147 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
4151 if (dump_file && (dump_flags & TDF_DETAILS))
4153 fprintf (dump_file, "with stmt:");
4154 print_gimple_stmt (dump_file, new_stmt, 0, 0);
4155 fprintf (dump_file, "\n");
4157 gsi_replace (&gsi, new_stmt, true);
4158 if (cs)
4159 cs->set_call_stmt (new_stmt);
4162 current_node->record_stmt_references (gsi_stmt (gsi));
4163 gsi_prev (&gsi);
4165 while (gsi_stmt (gsi) != gsi_stmt (prev_gsi));
4168 /* If the expression *EXPR should be replaced by a reduction of a parameter, do
4169 so. ADJUSTMENTS is a pointer to a vector of adjustments. CONVERT
4170 specifies whether the function should care about type incompatibility the
4171 current and new expressions. If it is false, the function will leave
4172 incompatibility issues to the caller. Return true iff the expression
4173 was modified. */
4175 bool
4176 ipa_modify_expr (tree *expr, bool convert,
4177 ipa_parm_adjustment_vec adjustments)
4179 struct ipa_parm_adjustment *cand
4180 = ipa_get_adjustment_candidate (&expr, &convert, adjustments, false);
4181 if (!cand)
4182 return false;
4184 tree src;
4185 if (cand->by_ref)
4186 src = build_simple_mem_ref (cand->new_decl);
4187 else
4188 src = cand->new_decl;
4190 if (dump_file && (dump_flags & TDF_DETAILS))
4192 fprintf (dump_file, "About to replace expr ");
4193 print_generic_expr (dump_file, *expr, 0);
4194 fprintf (dump_file, " with ");
4195 print_generic_expr (dump_file, src, 0);
4196 fprintf (dump_file, "\n");
4199 if (convert && !useless_type_conversion_p (TREE_TYPE (*expr), cand->type))
4201 tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*expr), src);
4202 *expr = vce;
4204 else
4205 *expr = src;
4206 return true;
4209 /* If T is an SSA_NAME, return NULL if it is not a default def or
4210 return its base variable if it is. If IGNORE_DEFAULT_DEF is true,
4211 the base variable is always returned, regardless if it is a default
4212 def. Return T if it is not an SSA_NAME. */
4214 static tree
4215 get_ssa_base_param (tree t, bool ignore_default_def)
4217 if (TREE_CODE (t) == SSA_NAME)
4219 if (ignore_default_def || SSA_NAME_IS_DEFAULT_DEF (t))
4220 return SSA_NAME_VAR (t);
4221 else
4222 return NULL_TREE;
4224 return t;
4227 /* Given an expression, return an adjustment entry specifying the
4228 transformation to be done on EXPR. If no suitable adjustment entry
4229 was found, returns NULL.
4231 If IGNORE_DEFAULT_DEF is set, consider SSA_NAMEs which are not a
4232 default def, otherwise bail on them.
4234 If CONVERT is non-NULL, this function will set *CONVERT if the
4235 expression provided is a component reference. ADJUSTMENTS is the
4236 adjustments vector. */
4238 ipa_parm_adjustment *
4239 ipa_get_adjustment_candidate (tree **expr, bool *convert,
4240 ipa_parm_adjustment_vec adjustments,
4241 bool ignore_default_def)
4243 if (TREE_CODE (**expr) == BIT_FIELD_REF
4244 || TREE_CODE (**expr) == IMAGPART_EXPR
4245 || TREE_CODE (**expr) == REALPART_EXPR)
4247 *expr = &TREE_OPERAND (**expr, 0);
4248 if (convert)
4249 *convert = true;
4252 HOST_WIDE_INT offset, size, max_size;
4253 tree base = get_ref_base_and_extent (**expr, &offset, &size, &max_size);
4254 if (!base || size == -1 || max_size == -1)
4255 return NULL;
4257 if (TREE_CODE (base) == MEM_REF)
4259 offset += mem_ref_offset (base).to_short_addr () * BITS_PER_UNIT;
4260 base = TREE_OPERAND (base, 0);
4263 base = get_ssa_base_param (base, ignore_default_def);
4264 if (!base || TREE_CODE (base) != PARM_DECL)
4265 return NULL;
4267 struct ipa_parm_adjustment *cand = NULL;
4268 unsigned int len = adjustments.length ();
4269 for (unsigned i = 0; i < len; i++)
4271 struct ipa_parm_adjustment *adj = &adjustments[i];
4273 if (adj->base == base
4274 && (adj->offset == offset || adj->op == IPA_PARM_OP_REMOVE))
4276 cand = adj;
4277 break;
4281 if (!cand || cand->op == IPA_PARM_OP_COPY || cand->op == IPA_PARM_OP_REMOVE)
4282 return NULL;
4283 return cand;
4286 /* Return true iff BASE_INDEX is in ADJUSTMENTS more than once. */
4288 static bool
4289 index_in_adjustments_multiple_times_p (int base_index,
4290 ipa_parm_adjustment_vec adjustments)
4292 int i, len = adjustments.length ();
4293 bool one = false;
4295 for (i = 0; i < len; i++)
4297 struct ipa_parm_adjustment *adj;
4298 adj = &adjustments[i];
4300 if (adj->base_index == base_index)
4302 if (one)
4303 return true;
4304 else
4305 one = true;
4308 return false;
4312 /* Return adjustments that should have the same effect on function parameters
4313 and call arguments as if they were first changed according to adjustments in
4314 INNER and then by adjustments in OUTER. */
4316 ipa_parm_adjustment_vec
4317 ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
4318 ipa_parm_adjustment_vec outer)
4320 int i, outlen = outer.length ();
4321 int inlen = inner.length ();
4322 int removals = 0;
4323 ipa_parm_adjustment_vec adjustments, tmp;
4325 tmp.create (inlen);
4326 for (i = 0; i < inlen; i++)
4328 struct ipa_parm_adjustment *n;
4329 n = &inner[i];
4331 if (n->op == IPA_PARM_OP_REMOVE)
4332 removals++;
4333 else
4335 /* FIXME: Handling of new arguments are not implemented yet. */
4336 gcc_assert (n->op != IPA_PARM_OP_NEW);
4337 tmp.quick_push (*n);
4341 adjustments.create (outlen + removals);
4342 for (i = 0; i < outlen; i++)
4344 struct ipa_parm_adjustment r;
4345 struct ipa_parm_adjustment *out = &outer[i];
4346 struct ipa_parm_adjustment *in = &tmp[out->base_index];
4348 memset (&r, 0, sizeof (r));
4349 gcc_assert (in->op != IPA_PARM_OP_REMOVE);
4350 if (out->op == IPA_PARM_OP_REMOVE)
4352 if (!index_in_adjustments_multiple_times_p (in->base_index, tmp))
4354 r.op = IPA_PARM_OP_REMOVE;
4355 adjustments.quick_push (r);
4357 continue;
4359 else
4361 /* FIXME: Handling of new arguments are not implemented yet. */
4362 gcc_assert (out->op != IPA_PARM_OP_NEW);
4365 r.base_index = in->base_index;
4366 r.type = out->type;
4368 /* FIXME: Create nonlocal value too. */
4370 if (in->op == IPA_PARM_OP_COPY && out->op == IPA_PARM_OP_COPY)
4371 r.op = IPA_PARM_OP_COPY;
4372 else if (in->op == IPA_PARM_OP_COPY)
4373 r.offset = out->offset;
4374 else if (out->op == IPA_PARM_OP_COPY)
4375 r.offset = in->offset;
4376 else
4377 r.offset = in->offset + out->offset;
4378 adjustments.quick_push (r);
4381 for (i = 0; i < inlen; i++)
4383 struct ipa_parm_adjustment *n = &inner[i];
4385 if (n->op == IPA_PARM_OP_REMOVE)
4386 adjustments.quick_push (*n);
4389 tmp.release ();
4390 return adjustments;
4393 /* Dump the adjustments in the vector ADJUSTMENTS to dump_file in a human
4394 friendly way, assuming they are meant to be applied to FNDECL. */
4396 void
4397 ipa_dump_param_adjustments (FILE *file, ipa_parm_adjustment_vec adjustments,
4398 tree fndecl)
4400 int i, len = adjustments.length ();
4401 bool first = true;
4402 vec<tree> parms = ipa_get_vector_of_formal_parms (fndecl);
4404 fprintf (file, "IPA param adjustments: ");
4405 for (i = 0; i < len; i++)
4407 struct ipa_parm_adjustment *adj;
4408 adj = &adjustments[i];
4410 if (!first)
4411 fprintf (file, " ");
4412 else
4413 first = false;
4415 fprintf (file, "%i. base_index: %i - ", i, adj->base_index);
4416 print_generic_expr (file, parms[adj->base_index], 0);
4417 if (adj->base)
4419 fprintf (file, ", base: ");
4420 print_generic_expr (file, adj->base, 0);
4422 if (adj->new_decl)
4424 fprintf (file, ", new_decl: ");
4425 print_generic_expr (file, adj->new_decl, 0);
4427 if (adj->new_ssa_base)
4429 fprintf (file, ", new_ssa_base: ");
4430 print_generic_expr (file, adj->new_ssa_base, 0);
4433 if (adj->op == IPA_PARM_OP_COPY)
4434 fprintf (file, ", copy_param");
4435 else if (adj->op == IPA_PARM_OP_REMOVE)
4436 fprintf (file, ", remove_param");
4437 else
4438 fprintf (file, ", offset %li", (long) adj->offset);
4439 if (adj->by_ref)
4440 fprintf (file, ", by_ref");
4441 print_node_brief (file, ", type: ", adj->type, 0);
4442 fprintf (file, "\n");
4444 parms.release ();
4447 /* Dump the AV linked list. */
4449 void
4450 ipa_dump_agg_replacement_values (FILE *f, struct ipa_agg_replacement_value *av)
4452 bool comma = false;
4453 fprintf (f, " Aggregate replacements:");
4454 for (; av; av = av->next)
4456 fprintf (f, "%s %i[" HOST_WIDE_INT_PRINT_DEC "]=", comma ? "," : "",
4457 av->index, av->offset);
4458 print_generic_expr (f, av->value, 0);
4459 comma = true;
4461 fprintf (f, "\n");
4464 /* Stream out jump function JUMP_FUNC to OB. */
4466 static void
4467 ipa_write_jump_function (struct output_block *ob,
4468 struct ipa_jump_func *jump_func)
4470 struct ipa_agg_jf_item *item;
4471 struct bitpack_d bp;
4472 int i, count;
4474 streamer_write_uhwi (ob, jump_func->type);
4475 switch (jump_func->type)
4477 case IPA_JF_UNKNOWN:
4478 break;
4479 case IPA_JF_CONST:
4480 gcc_assert (
4481 EXPR_LOCATION (jump_func->value.constant.value) == UNKNOWN_LOCATION);
4482 stream_write_tree (ob, jump_func->value.constant.value, true);
4483 break;
4484 case IPA_JF_PASS_THROUGH:
4485 streamer_write_uhwi (ob, jump_func->value.pass_through.operation);
4486 if (jump_func->value.pass_through.operation == NOP_EXPR)
4488 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4489 bp = bitpack_create (ob->main_stream);
4490 bp_pack_value (&bp, jump_func->value.pass_through.agg_preserved, 1);
4491 streamer_write_bitpack (&bp);
4493 else
4495 stream_write_tree (ob, jump_func->value.pass_through.operand, true);
4496 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4498 break;
4499 case IPA_JF_ANCESTOR:
4500 streamer_write_uhwi (ob, jump_func->value.ancestor.offset);
4501 streamer_write_uhwi (ob, jump_func->value.ancestor.formal_id);
4502 bp = bitpack_create (ob->main_stream);
4503 bp_pack_value (&bp, jump_func->value.ancestor.agg_preserved, 1);
4504 streamer_write_bitpack (&bp);
4505 break;
4508 count = vec_safe_length (jump_func->agg.items);
4509 streamer_write_uhwi (ob, count);
4510 if (count)
4512 bp = bitpack_create (ob->main_stream);
4513 bp_pack_value (&bp, jump_func->agg.by_ref, 1);
4514 streamer_write_bitpack (&bp);
4517 FOR_EACH_VEC_SAFE_ELT (jump_func->agg.items, i, item)
4519 streamer_write_uhwi (ob, item->offset);
4520 stream_write_tree (ob, item->value, true);
4523 bp = bitpack_create (ob->main_stream);
4524 bp_pack_value (&bp, jump_func->alignment.known, 1);
4525 streamer_write_bitpack (&bp);
4526 if (jump_func->alignment.known)
4528 streamer_write_uhwi (ob, jump_func->alignment.align);
4529 streamer_write_uhwi (ob, jump_func->alignment.misalign);
4533 /* Read in jump function JUMP_FUNC from IB. */
4535 static void
4536 ipa_read_jump_function (struct lto_input_block *ib,
4537 struct ipa_jump_func *jump_func,
4538 struct cgraph_edge *cs,
4539 struct data_in *data_in)
4541 enum jump_func_type jftype;
4542 enum tree_code operation;
4543 int i, count;
4545 jftype = (enum jump_func_type) streamer_read_uhwi (ib);
4546 switch (jftype)
4548 case IPA_JF_UNKNOWN:
4549 ipa_set_jf_unknown (jump_func);
4550 break;
4551 case IPA_JF_CONST:
4552 ipa_set_jf_constant (jump_func, stream_read_tree (ib, data_in), cs);
4553 break;
4554 case IPA_JF_PASS_THROUGH:
4555 operation = (enum tree_code) streamer_read_uhwi (ib);
4556 if (operation == NOP_EXPR)
4558 int formal_id = streamer_read_uhwi (ib);
4559 struct bitpack_d bp = streamer_read_bitpack (ib);
4560 bool agg_preserved = bp_unpack_value (&bp, 1);
4561 ipa_set_jf_simple_pass_through (jump_func, formal_id, agg_preserved);
4563 else
4565 tree operand = stream_read_tree (ib, data_in);
4566 int formal_id = streamer_read_uhwi (ib);
4567 ipa_set_jf_arith_pass_through (jump_func, formal_id, operand,
4568 operation);
4570 break;
4571 case IPA_JF_ANCESTOR:
4573 HOST_WIDE_INT offset = streamer_read_uhwi (ib);
4574 int formal_id = streamer_read_uhwi (ib);
4575 struct bitpack_d bp = streamer_read_bitpack (ib);
4576 bool agg_preserved = bp_unpack_value (&bp, 1);
4577 ipa_set_ancestor_jf (jump_func, offset, formal_id, agg_preserved);
4578 break;
4582 count = streamer_read_uhwi (ib);
4583 vec_alloc (jump_func->agg.items, count);
4584 if (count)
4586 struct bitpack_d bp = streamer_read_bitpack (ib);
4587 jump_func->agg.by_ref = bp_unpack_value (&bp, 1);
4589 for (i = 0; i < count; i++)
4591 struct ipa_agg_jf_item item;
4592 item.offset = streamer_read_uhwi (ib);
4593 item.value = stream_read_tree (ib, data_in);
4594 jump_func->agg.items->quick_push (item);
4597 struct bitpack_d bp = streamer_read_bitpack (ib);
4598 bool alignment_known = bp_unpack_value (&bp, 1);
4599 if (alignment_known)
4601 jump_func->alignment.known = true;
4602 jump_func->alignment.align = streamer_read_uhwi (ib);
4603 jump_func->alignment.misalign = streamer_read_uhwi (ib);
4605 else
4606 jump_func->alignment.known = false;
4609 /* Stream out parts of cgraph_indirect_call_info corresponding to CS that are
4610 relevant to indirect inlining to OB. */
4612 static void
4613 ipa_write_indirect_edge_info (struct output_block *ob,
4614 struct cgraph_edge *cs)
4616 struct cgraph_indirect_call_info *ii = cs->indirect_info;
4617 struct bitpack_d bp;
4619 streamer_write_hwi (ob, ii->param_index);
4620 bp = bitpack_create (ob->main_stream);
4621 bp_pack_value (&bp, ii->polymorphic, 1);
4622 bp_pack_value (&bp, ii->agg_contents, 1);
4623 bp_pack_value (&bp, ii->member_ptr, 1);
4624 bp_pack_value (&bp, ii->by_ref, 1);
4625 bp_pack_value (&bp, ii->vptr_changed, 1);
4626 streamer_write_bitpack (&bp);
4627 if (ii->agg_contents || ii->polymorphic)
4628 streamer_write_hwi (ob, ii->offset);
4629 else
4630 gcc_assert (ii->offset == 0);
4632 if (ii->polymorphic)
4634 streamer_write_hwi (ob, ii->otr_token);
4635 stream_write_tree (ob, ii->otr_type, true);
4636 ii->context.stream_out (ob);
4640 /* Read in parts of cgraph_indirect_call_info corresponding to CS that are
4641 relevant to indirect inlining from IB. */
4643 static void
4644 ipa_read_indirect_edge_info (struct lto_input_block *ib,
4645 struct data_in *data_in,
4646 struct cgraph_edge *cs)
4648 struct cgraph_indirect_call_info *ii = cs->indirect_info;
4649 struct bitpack_d bp;
4651 ii->param_index = (int) streamer_read_hwi (ib);
4652 bp = streamer_read_bitpack (ib);
4653 ii->polymorphic = bp_unpack_value (&bp, 1);
4654 ii->agg_contents = bp_unpack_value (&bp, 1);
4655 ii->member_ptr = bp_unpack_value (&bp, 1);
4656 ii->by_ref = bp_unpack_value (&bp, 1);
4657 ii->vptr_changed = bp_unpack_value (&bp, 1);
4658 if (ii->agg_contents || ii->polymorphic)
4659 ii->offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
4660 else
4661 ii->offset = 0;
4662 if (ii->polymorphic)
4664 ii->otr_token = (HOST_WIDE_INT) streamer_read_hwi (ib);
4665 ii->otr_type = stream_read_tree (ib, data_in);
4666 ii->context.stream_in (ib, data_in);
4670 /* Stream out NODE info to OB. */
4672 static void
4673 ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
4675 int node_ref;
4676 lto_symtab_encoder_t encoder;
4677 struct ipa_node_params *info = IPA_NODE_REF (node);
4678 int j;
4679 struct cgraph_edge *e;
4680 struct bitpack_d bp;
4682 encoder = ob->decl_state->symtab_node_encoder;
4683 node_ref = lto_symtab_encoder_encode (encoder, node);
4684 streamer_write_uhwi (ob, node_ref);
4686 streamer_write_uhwi (ob, ipa_get_param_count (info));
4687 for (j = 0; j < ipa_get_param_count (info); j++)
4688 streamer_write_uhwi (ob, ipa_get_param_move_cost (info, j));
4689 bp = bitpack_create (ob->main_stream);
4690 gcc_assert (info->analysis_done
4691 || ipa_get_param_count (info) == 0);
4692 gcc_assert (!info->node_enqueued);
4693 gcc_assert (!info->ipcp_orig_node);
4694 for (j = 0; j < ipa_get_param_count (info); j++)
4695 bp_pack_value (&bp, ipa_is_param_used (info, j), 1);
4696 streamer_write_bitpack (&bp);
4697 for (j = 0; j < ipa_get_param_count (info); j++)
4698 streamer_write_hwi (ob, ipa_get_controlled_uses (info, j));
4699 for (e = node->callees; e; e = e->next_callee)
4701 struct ipa_edge_args *args = IPA_EDGE_REF (e);
4703 streamer_write_uhwi (ob,
4704 ipa_get_cs_argument_count (args) * 2
4705 + (args->polymorphic_call_contexts != NULL));
4706 for (j = 0; j < ipa_get_cs_argument_count (args); j++)
4708 ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
4709 if (args->polymorphic_call_contexts != NULL)
4710 ipa_get_ith_polymorhic_call_context (args, j)->stream_out (ob);
4713 for (e = node->indirect_calls; e; e = e->next_callee)
4715 struct ipa_edge_args *args = IPA_EDGE_REF (e);
4717 streamer_write_uhwi (ob,
4718 ipa_get_cs_argument_count (args) * 2
4719 + (args->polymorphic_call_contexts != NULL));
4720 for (j = 0; j < ipa_get_cs_argument_count (args); j++)
4722 ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
4723 if (args->polymorphic_call_contexts != NULL)
4724 ipa_get_ith_polymorhic_call_context (args, j)->stream_out (ob);
4726 ipa_write_indirect_edge_info (ob, e);
4730 /* Stream in NODE info from IB. */
4732 static void
4733 ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
4734 struct data_in *data_in)
4736 struct ipa_node_params *info = IPA_NODE_REF (node);
4737 int k;
4738 struct cgraph_edge *e;
4739 struct bitpack_d bp;
4741 ipa_alloc_node_params (node, streamer_read_uhwi (ib));
4743 for (k = 0; k < ipa_get_param_count (info); k++)
4744 info->descriptors[k].move_cost = streamer_read_uhwi (ib);
4746 bp = streamer_read_bitpack (ib);
4747 if (ipa_get_param_count (info) != 0)
4748 info->analysis_done = true;
4749 info->node_enqueued = false;
4750 for (k = 0; k < ipa_get_param_count (info); k++)
4751 ipa_set_param_used (info, k, bp_unpack_value (&bp, 1));
4752 for (k = 0; k < ipa_get_param_count (info); k++)
4753 ipa_set_controlled_uses (info, k, streamer_read_hwi (ib));
4754 for (e = node->callees; e; e = e->next_callee)
4756 struct ipa_edge_args *args = IPA_EDGE_REF (e);
4757 int count = streamer_read_uhwi (ib);
4758 bool contexts_computed = count & 1;
4759 count /= 2;
4761 if (!count)
4762 continue;
4763 vec_safe_grow_cleared (args->jump_functions, count);
4764 if (contexts_computed)
4765 vec_safe_grow_cleared (args->polymorphic_call_contexts, count);
4767 for (k = 0; k < ipa_get_cs_argument_count (args); k++)
4769 ipa_read_jump_function (ib, ipa_get_ith_jump_func (args, k), e,
4770 data_in);
4771 if (contexts_computed)
4772 ipa_get_ith_polymorhic_call_context (args, k)->stream_in (ib, data_in);
4775 for (e = node->indirect_calls; e; e = e->next_callee)
4777 struct ipa_edge_args *args = IPA_EDGE_REF (e);
4778 int count = streamer_read_uhwi (ib);
4779 bool contexts_computed = count & 1;
4780 count /= 2;
4782 if (count)
4784 vec_safe_grow_cleared (args->jump_functions, count);
4785 if (contexts_computed)
4786 vec_safe_grow_cleared (args->polymorphic_call_contexts, count);
4787 for (k = 0; k < ipa_get_cs_argument_count (args); k++)
4789 ipa_read_jump_function (ib, ipa_get_ith_jump_func (args, k), e,
4790 data_in);
4791 if (contexts_computed)
4792 ipa_get_ith_polymorhic_call_context (args, k)->stream_in (ib, data_in);
4795 ipa_read_indirect_edge_info (ib, data_in, e);
4799 /* Write jump functions for nodes in SET. */
4801 void
4802 ipa_prop_write_jump_functions (void)
4804 struct cgraph_node *node;
4805 struct output_block *ob;
4806 unsigned int count = 0;
4807 lto_symtab_encoder_iterator lsei;
4808 lto_symtab_encoder_t encoder;
4810 if (!ipa_node_params_sum)
4811 return;
4813 ob = create_output_block (LTO_section_jump_functions);
4814 encoder = ob->decl_state->symtab_node_encoder;
4815 ob->symbol = NULL;
4816 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
4817 lsei_next_function_in_partition (&lsei))
4819 node = lsei_cgraph_node (lsei);
4820 if (node->has_gimple_body_p ()
4821 && IPA_NODE_REF (node) != NULL)
4822 count++;
4825 streamer_write_uhwi (ob, count);
4827 /* Process all of the functions. */
4828 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
4829 lsei_next_function_in_partition (&lsei))
4831 node = lsei_cgraph_node (lsei);
4832 if (node->has_gimple_body_p ()
4833 && IPA_NODE_REF (node) != NULL)
4834 ipa_write_node_info (ob, node);
4836 streamer_write_char_stream (ob->main_stream, 0);
4837 produce_asm (ob, NULL);
4838 destroy_output_block (ob);
4841 /* Read section in file FILE_DATA of length LEN with data DATA. */
4843 static void
4844 ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
4845 size_t len)
4847 const struct lto_function_header *header =
4848 (const struct lto_function_header *) data;
4849 const int cfg_offset = sizeof (struct lto_function_header);
4850 const int main_offset = cfg_offset + header->cfg_size;
4851 const int string_offset = main_offset + header->main_size;
4852 struct data_in *data_in;
4853 unsigned int i;
4854 unsigned int count;
4856 lto_input_block ib_main ((const char *) data + main_offset,
4857 header->main_size, file_data->mode_table);
4859 data_in =
4860 lto_data_in_create (file_data, (const char *) data + string_offset,
4861 header->string_size, vNULL);
4862 count = streamer_read_uhwi (&ib_main);
4864 for (i = 0; i < count; i++)
4866 unsigned int index;
4867 struct cgraph_node *node;
4868 lto_symtab_encoder_t encoder;
4870 index = streamer_read_uhwi (&ib_main);
4871 encoder = file_data->symtab_node_encoder;
4872 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
4873 index));
4874 gcc_assert (node->definition);
4875 ipa_read_node_info (&ib_main, node, data_in);
4877 lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
4878 len);
4879 lto_data_in_delete (data_in);
4882 /* Read ipcp jump functions. */
4884 void
4885 ipa_prop_read_jump_functions (void)
4887 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
4888 struct lto_file_decl_data *file_data;
4889 unsigned int j = 0;
4891 ipa_check_create_node_params ();
4892 ipa_check_create_edge_args ();
4893 ipa_register_cgraph_hooks ();
4895 while ((file_data = file_data_vec[j++]))
4897 size_t len;
4898 const char *data = lto_get_section_data (file_data, LTO_section_jump_functions, NULL, &len);
4900 if (data)
4901 ipa_prop_read_section (file_data, data, len);
4905 /* After merging units, we can get mismatch in argument counts.
4906 Also decl merging might've rendered parameter lists obsolete.
4907 Also compute called_with_variable_arg info. */
4909 void
4910 ipa_update_after_lto_read (void)
4912 ipa_check_create_node_params ();
4913 ipa_check_create_edge_args ();
4916 void
4917 write_ipcp_transformation_info (output_block *ob, cgraph_node *node)
4919 int node_ref;
4920 unsigned int count = 0;
4921 lto_symtab_encoder_t encoder;
4922 struct ipa_agg_replacement_value *aggvals, *av;
4924 aggvals = ipa_get_agg_replacements_for_node (node);
4925 encoder = ob->decl_state->symtab_node_encoder;
4926 node_ref = lto_symtab_encoder_encode (encoder, node);
4927 streamer_write_uhwi (ob, node_ref);
4929 for (av = aggvals; av; av = av->next)
4930 count++;
4931 streamer_write_uhwi (ob, count);
4933 for (av = aggvals; av; av = av->next)
4935 struct bitpack_d bp;
4937 streamer_write_uhwi (ob, av->offset);
4938 streamer_write_uhwi (ob, av->index);
4939 stream_write_tree (ob, av->value, true);
4941 bp = bitpack_create (ob->main_stream);
4942 bp_pack_value (&bp, av->by_ref, 1);
4943 streamer_write_bitpack (&bp);
4946 ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node);
4947 if (ts && vec_safe_length (ts->alignments) > 0)
4949 count = ts->alignments->length ();
4951 streamer_write_uhwi (ob, count);
4952 for (unsigned i = 0; i < count; ++i)
4954 ipa_alignment *parm_al = &(*ts->alignments)[i];
4956 struct bitpack_d bp;
4957 bp = bitpack_create (ob->main_stream);
4958 bp_pack_value (&bp, parm_al->known, 1);
4959 streamer_write_bitpack (&bp);
4960 if (parm_al->known)
4962 streamer_write_uhwi (ob, parm_al->align);
4963 streamer_write_hwi_in_range (ob->main_stream, 0, parm_al->align,
4964 parm_al->misalign);
4968 else
4969 streamer_write_uhwi (ob, 0);
4972 /* Stream in the aggregate value replacement chain for NODE from IB. */
4974 static void
4975 read_ipcp_transformation_info (lto_input_block *ib, cgraph_node *node,
4976 data_in *data_in)
4978 struct ipa_agg_replacement_value *aggvals = NULL;
4979 unsigned int count, i;
4981 count = streamer_read_uhwi (ib);
4982 for (i = 0; i <count; i++)
4984 struct ipa_agg_replacement_value *av;
4985 struct bitpack_d bp;
4987 av = ggc_alloc<ipa_agg_replacement_value> ();
4988 av->offset = streamer_read_uhwi (ib);
4989 av->index = streamer_read_uhwi (ib);
4990 av->value = stream_read_tree (ib, data_in);
4991 bp = streamer_read_bitpack (ib);
4992 av->by_ref = bp_unpack_value (&bp, 1);
4993 av->next = aggvals;
4994 aggvals = av;
4996 ipa_set_node_agg_value_chain (node, aggvals);
4998 count = streamer_read_uhwi (ib);
4999 if (count > 0)
5001 ipcp_grow_transformations_if_necessary ();
5003 ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node);
5004 vec_safe_grow_cleared (ts->alignments, count);
5006 for (i = 0; i < count; i++)
5008 ipa_alignment *parm_al;
5009 parm_al = &(*ts->alignments)[i];
5010 struct bitpack_d bp;
5011 bp = streamer_read_bitpack (ib);
5012 parm_al->known = bp_unpack_value (&bp, 1);
5013 if (parm_al->known)
5015 parm_al->align = streamer_read_uhwi (ib);
5016 parm_al->misalign
5017 = streamer_read_hwi_in_range (ib, "ipa-prop misalign",
5018 0, parm_al->align);
5024 /* Write all aggregate replacement for nodes in set. */
5026 void
5027 ipcp_write_transformation_summaries (void)
5029 struct cgraph_node *node;
5030 struct output_block *ob;
5031 unsigned int count = 0;
5032 lto_symtab_encoder_iterator lsei;
5033 lto_symtab_encoder_t encoder;
5035 ob = create_output_block (LTO_section_ipcp_transform);
5036 encoder = ob->decl_state->symtab_node_encoder;
5037 ob->symbol = NULL;
5038 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
5039 lsei_next_function_in_partition (&lsei))
5041 node = lsei_cgraph_node (lsei);
5042 if (node->has_gimple_body_p ())
5043 count++;
5046 streamer_write_uhwi (ob, count);
5048 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
5049 lsei_next_function_in_partition (&lsei))
5051 node = lsei_cgraph_node (lsei);
5052 if (node->has_gimple_body_p ())
5053 write_ipcp_transformation_info (ob, node);
5055 streamer_write_char_stream (ob->main_stream, 0);
5056 produce_asm (ob, NULL);
5057 destroy_output_block (ob);
5060 /* Read replacements section in file FILE_DATA of length LEN with data
5061 DATA. */
5063 static void
5064 read_replacements_section (struct lto_file_decl_data *file_data,
5065 const char *data,
5066 size_t len)
5068 const struct lto_function_header *header =
5069 (const struct lto_function_header *) data;
5070 const int cfg_offset = sizeof (struct lto_function_header);
5071 const int main_offset = cfg_offset + header->cfg_size;
5072 const int string_offset = main_offset + header->main_size;
5073 struct data_in *data_in;
5074 unsigned int i;
5075 unsigned int count;
5077 lto_input_block ib_main ((const char *) data + main_offset,
5078 header->main_size, file_data->mode_table);
5080 data_in = lto_data_in_create (file_data, (const char *) data + string_offset,
5081 header->string_size, vNULL);
5082 count = streamer_read_uhwi (&ib_main);
5084 for (i = 0; i < count; i++)
5086 unsigned int index;
5087 struct cgraph_node *node;
5088 lto_symtab_encoder_t encoder;
5090 index = streamer_read_uhwi (&ib_main);
5091 encoder = file_data->symtab_node_encoder;
5092 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
5093 index));
5094 gcc_assert (node->definition);
5095 read_ipcp_transformation_info (&ib_main, node, data_in);
5097 lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
5098 len);
5099 lto_data_in_delete (data_in);
5102 /* Read IPA-CP aggregate replacements. */
5104 void
5105 ipcp_read_transformation_summaries (void)
5107 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
5108 struct lto_file_decl_data *file_data;
5109 unsigned int j = 0;
5111 while ((file_data = file_data_vec[j++]))
5113 size_t len;
5114 const char *data = lto_get_section_data (file_data,
5115 LTO_section_ipcp_transform,
5116 NULL, &len);
5117 if (data)
5118 read_replacements_section (file_data, data, len);
5122 /* Adjust the aggregate replacements in AGGVAL to reflect parameters skipped in
5123 NODE. */
5125 static void
5126 adjust_agg_replacement_values (struct cgraph_node *node,
5127 struct ipa_agg_replacement_value *aggval)
5129 struct ipa_agg_replacement_value *v;
5130 int i, c = 0, d = 0, *adj;
5132 if (!node->clone.combined_args_to_skip)
5133 return;
5135 for (v = aggval; v; v = v->next)
5137 gcc_assert (v->index >= 0);
5138 if (c < v->index)
5139 c = v->index;
5141 c++;
5143 adj = XALLOCAVEC (int, c);
5144 for (i = 0; i < c; i++)
5145 if (bitmap_bit_p (node->clone.combined_args_to_skip, i))
5147 adj[i] = -1;
5148 d++;
5150 else
5151 adj[i] = i - d;
5153 for (v = aggval; v; v = v->next)
5154 v->index = adj[v->index];
5157 /* Dominator walker driving the ipcp modification phase. */
5159 class ipcp_modif_dom_walker : public dom_walker
5161 public:
5162 ipcp_modif_dom_walker (struct func_body_info *fbi,
5163 vec<ipa_param_descriptor> descs,
5164 struct ipa_agg_replacement_value *av,
5165 bool *sc, bool *cc)
5166 : dom_walker (CDI_DOMINATORS), m_fbi (fbi), m_descriptors (descs),
5167 m_aggval (av), m_something_changed (sc), m_cfg_changed (cc) {}
5169 virtual void before_dom_children (basic_block);
5171 private:
5172 struct func_body_info *m_fbi;
5173 vec<ipa_param_descriptor> m_descriptors;
5174 struct ipa_agg_replacement_value *m_aggval;
5175 bool *m_something_changed, *m_cfg_changed;
5178 void
5179 ipcp_modif_dom_walker::before_dom_children (basic_block bb)
5181 gimple_stmt_iterator gsi;
5182 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
5184 struct ipa_agg_replacement_value *v;
5185 gimple stmt = gsi_stmt (gsi);
5186 tree rhs, val, t;
5187 HOST_WIDE_INT offset, size;
5188 int index;
5189 bool by_ref, vce;
5191 if (!gimple_assign_load_p (stmt))
5192 continue;
5193 rhs = gimple_assign_rhs1 (stmt);
5194 if (!is_gimple_reg_type (TREE_TYPE (rhs)))
5195 continue;
5197 vce = false;
5198 t = rhs;
5199 while (handled_component_p (t))
5201 /* V_C_E can do things like convert an array of integers to one
5202 bigger integer and similar things we do not handle below. */
5203 if (TREE_CODE (rhs) == VIEW_CONVERT_EXPR)
5205 vce = true;
5206 break;
5208 t = TREE_OPERAND (t, 0);
5210 if (vce)
5211 continue;
5213 if (!ipa_load_from_parm_agg_1 (m_fbi, m_descriptors, stmt, rhs, &index,
5214 &offset, &size, &by_ref))
5215 continue;
5216 for (v = m_aggval; v; v = v->next)
5217 if (v->index == index
5218 && v->offset == offset)
5219 break;
5220 if (!v
5221 || v->by_ref != by_ref
5222 || tree_to_shwi (TYPE_SIZE (TREE_TYPE (v->value))) != size)
5223 continue;
5225 gcc_checking_assert (is_gimple_ip_invariant (v->value));
5226 if (!useless_type_conversion_p (TREE_TYPE (rhs), TREE_TYPE (v->value)))
5228 if (fold_convertible_p (TREE_TYPE (rhs), v->value))
5229 val = fold_build1 (NOP_EXPR, TREE_TYPE (rhs), v->value);
5230 else if (TYPE_SIZE (TREE_TYPE (rhs))
5231 == TYPE_SIZE (TREE_TYPE (v->value)))
5232 val = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (rhs), v->value);
5233 else
5235 if (dump_file)
5237 fprintf (dump_file, " const ");
5238 print_generic_expr (dump_file, v->value, 0);
5239 fprintf (dump_file, " can't be converted to type of ");
5240 print_generic_expr (dump_file, rhs, 0);
5241 fprintf (dump_file, "\n");
5243 continue;
5246 else
5247 val = v->value;
5249 if (dump_file && (dump_flags & TDF_DETAILS))
5251 fprintf (dump_file, "Modifying stmt:\n ");
5252 print_gimple_stmt (dump_file, stmt, 0, 0);
5254 gimple_assign_set_rhs_from_tree (&gsi, val);
5255 update_stmt (stmt);
5257 if (dump_file && (dump_flags & TDF_DETAILS))
5259 fprintf (dump_file, "into:\n ");
5260 print_gimple_stmt (dump_file, stmt, 0, 0);
5261 fprintf (dump_file, "\n");
5264 *m_something_changed = true;
5265 if (maybe_clean_eh_stmt (stmt)
5266 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
5267 *m_cfg_changed = true;
5272 /* Update alignment of formal parameters as described in
5273 ipcp_transformation_summary. */
5275 static void
5276 ipcp_update_alignments (struct cgraph_node *node)
5278 tree fndecl = node->decl;
5279 tree parm = DECL_ARGUMENTS (fndecl);
5280 tree next_parm = parm;
5281 ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node);
5282 if (!ts || vec_safe_length (ts->alignments) == 0)
5283 return;
5284 const vec<ipa_alignment, va_gc> &alignments = *ts->alignments;
5285 unsigned count = alignments.length ();
5287 for (unsigned i = 0; i < count; ++i, parm = next_parm)
5289 if (node->clone.combined_args_to_skip
5290 && bitmap_bit_p (node->clone.combined_args_to_skip, i))
5291 continue;
5292 gcc_checking_assert (parm);
5293 next_parm = DECL_CHAIN (parm);
5295 if (!alignments[i].known || !is_gimple_reg (parm))
5296 continue;
5297 tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl), parm);
5298 if (!ddef)
5299 continue;
5301 if (dump_file)
5302 fprintf (dump_file, " Adjusting alignment of param %u to %u, "
5303 "misalignment to %u\n", i, alignments[i].align,
5304 alignments[i].misalign);
5306 struct ptr_info_def *pi = get_ptr_info (ddef);
5307 gcc_checking_assert (pi);
5308 unsigned old_align;
5309 unsigned old_misalign;
5310 bool old_known = get_ptr_info_alignment (pi, &old_align, &old_misalign);
5312 if (old_known
5313 && old_align >= alignments[i].align)
5315 if (dump_file)
5316 fprintf (dump_file, " But the alignment was already %u.\n",
5317 old_align);
5318 continue;
5320 set_ptr_info_alignment (pi, alignments[i].align, alignments[i].misalign);
5324 /* IPCP transformation phase doing propagation of aggregate values. */
5326 unsigned int
5327 ipcp_transform_function (struct cgraph_node *node)
5329 vec<ipa_param_descriptor> descriptors = vNULL;
5330 struct func_body_info fbi;
5331 struct ipa_agg_replacement_value *aggval;
5332 int param_count;
5333 bool cfg_changed = false, something_changed = false;
5335 gcc_checking_assert (cfun);
5336 gcc_checking_assert (current_function_decl);
5338 if (dump_file)
5339 fprintf (dump_file, "Modification phase of node %s/%i\n",
5340 node->name (), node->order);
5342 ipcp_update_alignments (node);
5343 aggval = ipa_get_agg_replacements_for_node (node);
5344 if (!aggval)
5345 return 0;
5346 param_count = count_formal_params (node->decl);
5347 if (param_count == 0)
5348 return 0;
5349 adjust_agg_replacement_values (node, aggval);
5350 if (dump_file)
5351 ipa_dump_agg_replacement_values (dump_file, aggval);
5353 fbi.node = node;
5354 fbi.info = NULL;
5355 fbi.bb_infos = vNULL;
5356 fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun));
5357 fbi.param_count = param_count;
5358 fbi.aa_walked = 0;
5360 descriptors.safe_grow_cleared (param_count);
5361 ipa_populate_param_decls (node, descriptors);
5362 calculate_dominance_info (CDI_DOMINATORS);
5363 ipcp_modif_dom_walker (&fbi, descriptors, aggval, &something_changed,
5364 &cfg_changed).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
5366 int i;
5367 struct ipa_bb_info *bi;
5368 FOR_EACH_VEC_ELT (fbi.bb_infos, i, bi)
5369 free_ipa_bb_info (bi);
5370 fbi.bb_infos.release ();
5371 free_dominance_info (CDI_DOMINATORS);
5372 (*ipcp_transformations)[node->uid].agg_values = NULL;
5373 (*ipcp_transformations)[node->uid].alignments = NULL;
5374 descriptors.release ();
5376 if (!something_changed)
5377 return 0;
5378 else if (cfg_changed)
5379 return TODO_update_ssa_only_virtuals | TODO_cleanup_cfg;
5380 else
5381 return TODO_update_ssa_only_virtuals;