ipa-prop uses symbol_summary class.
[official-gcc.git] / gcc / ipa-prop.c
blobfebcd0cef87dc3cc6325d67521bcc753290f4c9f
1 /* Interprocedural analyses.
2 Copyright (C) 2005-2014 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 "tree.h"
24 #include "predict.h"
25 #include "vec.h"
26 #include "hashtab.h"
27 #include "hash-set.h"
28 #include "machmode.h"
29 #include "tm.h"
30 #include "hard-reg-set.h"
31 #include "input.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 "expr.h"
44 #include "stor-layout.h"
45 #include "print-tree.h"
46 #include "gimplify.h"
47 #include "gimple-iterator.h"
48 #include "gimplify-me.h"
49 #include "gimple-walk.h"
50 #include "langhooks.h"
51 #include "target.h"
52 #include "hash-map.h"
53 #include "plugin-api.h"
54 #include "ipa-ref.h"
55 #include "cgraph.h"
56 #include "alloc-pool.h"
57 #include "symbol-summary.h"
58 #include "ipa-prop.h"
59 #include "bitmap.h"
60 #include "gimple-ssa.h"
61 #include "tree-cfg.h"
62 #include "tree-phinodes.h"
63 #include "ssa-iterators.h"
64 #include "tree-into-ssa.h"
65 #include "tree-dfa.h"
66 #include "tree-pass.h"
67 #include "tree-inline.h"
68 #include "ipa-inline.h"
69 #include "flags.h"
70 #include "diagnostic.h"
71 #include "gimple-pretty-print.h"
72 #include "lto-streamer.h"
73 #include "data-streamer.h"
74 #include "tree-streamer.h"
75 #include "params.h"
76 #include "ipa-utils.h"
77 #include "stringpool.h"
78 #include "tree-ssanames.h"
79 #include "dbgcnt.h"
80 #include "domwalk.h"
81 #include "builtins.h"
82 #include "calls.h"
84 /* Intermediate information that we get from alias analysis about a particular
85 parameter in a particular basic_block. When a parameter or the memory it
86 references is marked modified, we use that information in all dominatd
87 blocks without cosulting alias analysis oracle. */
89 struct param_aa_status
91 /* Set when this structure contains meaningful information. If not, the
92 structure describing a dominating BB should be used instead. */
93 bool valid;
95 /* Whether we have seen something which might have modified the data in
96 question. PARM is for the parameter itself, REF is for data it points to
97 but using the alias type of individual accesses and PT is the same thing
98 but for computing aggregate pass-through functions using a very inclusive
99 ao_ref. */
100 bool parm_modified, ref_modified, pt_modified;
103 /* Information related to a given BB that used only when looking at function
104 body. */
106 struct ipa_bb_info
108 /* Call graph edges going out of this BB. */
109 vec<cgraph_edge *> cg_edges;
110 /* Alias analysis statuses of each formal parameter at this bb. */
111 vec<param_aa_status> param_aa_statuses;
114 /* Structure with global information that is only used when looking at function
115 body. */
117 struct func_body_info
119 /* The node that is being analyzed. */
120 cgraph_node *node;
122 /* Its info. */
123 struct ipa_node_params *info;
125 /* Information about individual BBs. */
126 vec<ipa_bb_info> bb_infos;
128 /* Number of parameters. */
129 int param_count;
131 /* Number of statements already walked by when analyzing this function. */
132 unsigned int aa_walked;
135 /* Function summary where the parameter infos are actually stored. */
136 ipa_node_params_t *ipa_node_params_sum = NULL;
137 /* Vector of IPA-CP transformation data for each clone. */
138 vec<ipcp_transformation_summary, va_gc> *ipcp_transformations;
139 /* Vector where the parameter infos are actually stored. */
140 vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
142 /* Holders of ipa cgraph hooks: */
143 static struct cgraph_edge_hook_list *edge_removal_hook_holder;
144 static struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
145 static struct cgraph_node_hook_list *function_insertion_hook_holder;
147 /* Description of a reference to an IPA constant. */
148 struct ipa_cst_ref_desc
150 /* Edge that corresponds to the statement which took the reference. */
151 struct cgraph_edge *cs;
152 /* Linked list of duplicates created when call graph edges are cloned. */
153 struct ipa_cst_ref_desc *next_duplicate;
154 /* Number of references in IPA structures, IPA_UNDESCRIBED_USE if the value
155 if out of control. */
156 int refcount;
159 /* Allocation pool for reference descriptions. */
161 static alloc_pool ipa_refdesc_pool;
163 /* Return true if DECL_FUNCTION_SPECIFIC_OPTIMIZATION of the decl associated
164 with NODE should prevent us from analyzing it for the purposes of IPA-CP. */
166 static bool
167 ipa_func_spec_opts_forbid_analysis_p (struct cgraph_node *node)
169 tree fs_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (node->decl);
171 if (!fs_opts)
172 return false;
173 return !opt_for_fn (node->decl, optimize) || !opt_for_fn (node->decl, flag_ipa_cp);
176 /* Return index of the formal whose tree is PTREE in function which corresponds
177 to INFO. */
179 static int
180 ipa_get_param_decl_index_1 (vec<ipa_param_descriptor> descriptors, tree ptree)
182 int i, count;
184 count = descriptors.length ();
185 for (i = 0; i < count; i++)
186 if (descriptors[i].decl == ptree)
187 return i;
189 return -1;
192 /* Return index of the formal whose tree is PTREE in function which corresponds
193 to INFO. */
196 ipa_get_param_decl_index (struct ipa_node_params *info, tree ptree)
198 return ipa_get_param_decl_index_1 (info->descriptors, ptree);
201 /* Populate the param_decl field in parameter DESCRIPTORS that correspond to
202 NODE. */
204 static void
205 ipa_populate_param_decls (struct cgraph_node *node,
206 vec<ipa_param_descriptor> &descriptors)
208 tree fndecl;
209 tree fnargs;
210 tree parm;
211 int param_num;
213 fndecl = node->decl;
214 gcc_assert (gimple_has_body_p (fndecl));
215 fnargs = DECL_ARGUMENTS (fndecl);
216 param_num = 0;
217 for (parm = fnargs; parm; parm = DECL_CHAIN (parm))
219 descriptors[param_num].decl = parm;
220 descriptors[param_num].move_cost = estimate_move_cost (TREE_TYPE (parm),
221 true);
222 param_num++;
226 /* Return how many formal parameters FNDECL has. */
229 count_formal_params (tree fndecl)
231 tree parm;
232 int count = 0;
233 gcc_assert (gimple_has_body_p (fndecl));
235 for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
236 count++;
238 return count;
241 /* Return the declaration of Ith formal parameter of the function corresponding
242 to INFO. Note there is no setter function as this array is built just once
243 using ipa_initialize_node_params. */
245 void
246 ipa_dump_param (FILE *file, struct ipa_node_params *info, int i)
248 fprintf (file, "param #%i", i);
249 if (info->descriptors[i].decl)
251 fprintf (file, " ");
252 print_generic_expr (file, info->descriptors[i].decl, 0);
256 /* Initialize the ipa_node_params structure associated with NODE
257 to hold PARAM_COUNT parameters. */
259 void
260 ipa_alloc_node_params (struct cgraph_node *node, int param_count)
262 struct ipa_node_params *info = IPA_NODE_REF (node);
264 if (!info->descriptors.exists () && param_count)
265 info->descriptors.safe_grow_cleared (param_count);
268 /* Initialize the ipa_node_params structure associated with NODE by counting
269 the function parameters, creating the descriptors and populating their
270 param_decls. */
272 void
273 ipa_initialize_node_params (struct cgraph_node *node)
275 struct ipa_node_params *info = IPA_NODE_REF (node);
277 if (!info->descriptors.exists ())
279 ipa_alloc_node_params (node, count_formal_params (node->decl));
280 ipa_populate_param_decls (node, info->descriptors);
284 /* Print the jump functions associated with call graph edge CS to file F. */
286 static void
287 ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
289 int i, count;
291 count = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
292 for (i = 0; i < count; i++)
294 struct ipa_jump_func *jump_func;
295 enum jump_func_type type;
297 jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
298 type = jump_func->type;
300 fprintf (f, " param %d: ", i);
301 if (type == IPA_JF_UNKNOWN)
302 fprintf (f, "UNKNOWN\n");
303 else if (type == IPA_JF_CONST)
305 tree val = jump_func->value.constant.value;
306 fprintf (f, "CONST: ");
307 print_generic_expr (f, val, 0);
308 if (TREE_CODE (val) == ADDR_EXPR
309 && TREE_CODE (TREE_OPERAND (val, 0)) == CONST_DECL)
311 fprintf (f, " -> ");
312 print_generic_expr (f, DECL_INITIAL (TREE_OPERAND (val, 0)),
315 fprintf (f, "\n");
317 else if (type == IPA_JF_PASS_THROUGH)
319 fprintf (f, "PASS THROUGH: ");
320 fprintf (f, "%d, op %s",
321 jump_func->value.pass_through.formal_id,
322 get_tree_code_name(jump_func->value.pass_through.operation));
323 if (jump_func->value.pass_through.operation != NOP_EXPR)
325 fprintf (f, " ");
326 print_generic_expr (f,
327 jump_func->value.pass_through.operand, 0);
329 if (jump_func->value.pass_through.agg_preserved)
330 fprintf (f, ", agg_preserved");
331 fprintf (f, "\n");
333 else if (type == IPA_JF_ANCESTOR)
335 fprintf (f, "ANCESTOR: ");
336 fprintf (f, "%d, offset "HOST_WIDE_INT_PRINT_DEC,
337 jump_func->value.ancestor.formal_id,
338 jump_func->value.ancestor.offset);
339 if (jump_func->value.ancestor.agg_preserved)
340 fprintf (f, ", agg_preserved");
341 fprintf (f, "\n");
344 if (jump_func->agg.items)
346 struct ipa_agg_jf_item *item;
347 int j;
349 fprintf (f, " Aggregate passed by %s:\n",
350 jump_func->agg.by_ref ? "reference" : "value");
351 FOR_EACH_VEC_SAFE_ELT (jump_func->agg.items, j, item)
353 fprintf (f, " offset: " HOST_WIDE_INT_PRINT_DEC ", ",
354 item->offset);
355 if (TYPE_P (item->value))
356 fprintf (f, "clobber of " HOST_WIDE_INT_PRINT_DEC " bits",
357 tree_to_uhwi (TYPE_SIZE (item->value)));
358 else
360 fprintf (f, "cst: ");
361 print_generic_expr (f, item->value, 0);
363 fprintf (f, "\n");
367 struct ipa_polymorphic_call_context *ctx
368 = ipa_get_ith_polymorhic_call_context (IPA_EDGE_REF (cs), i);
369 if (ctx && !ctx->useless_p ())
371 fprintf (f, " Context: ");
372 ctx->dump (dump_file);
375 if (jump_func->alignment.known)
377 fprintf (f, " Alignment: %u, misalignment: %u\n",
378 jump_func->alignment.align,
379 jump_func->alignment.misalign);
381 else
382 fprintf (f, " Unknown alignment\n");
387 /* Print the jump functions of all arguments on all call graph edges going from
388 NODE to file F. */
390 void
391 ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
393 struct cgraph_edge *cs;
395 fprintf (f, " Jump functions of caller %s/%i:\n", node->name (),
396 node->order);
397 for (cs = node->callees; cs; cs = cs->next_callee)
399 if (!ipa_edge_args_info_available_for_edge_p (cs))
400 continue;
402 fprintf (f, " callsite %s/%i -> %s/%i : \n",
403 xstrdup_for_dump (node->name ()), node->order,
404 xstrdup_for_dump (cs->callee->name ()),
405 cs->callee->order);
406 ipa_print_node_jump_functions_for_edge (f, cs);
409 for (cs = node->indirect_calls; cs; cs = cs->next_callee)
411 struct cgraph_indirect_call_info *ii;
412 if (!ipa_edge_args_info_available_for_edge_p (cs))
413 continue;
415 ii = cs->indirect_info;
416 if (ii->agg_contents)
417 fprintf (f, " indirect %s callsite, calling param %i, "
418 "offset " HOST_WIDE_INT_PRINT_DEC ", %s",
419 ii->member_ptr ? "member ptr" : "aggregate",
420 ii->param_index, ii->offset,
421 ii->by_ref ? "by reference" : "by_value");
422 else
423 fprintf (f, " indirect %s callsite, calling param %i, "
424 "offset " HOST_WIDE_INT_PRINT_DEC,
425 ii->polymorphic ? "polymorphic" : "simple", ii->param_index,
426 ii->offset);
428 if (cs->call_stmt)
430 fprintf (f, ", for stmt ");
431 print_gimple_stmt (f, cs->call_stmt, 0, TDF_SLIM);
433 else
434 fprintf (f, "\n");
435 if (ii->polymorphic)
436 ii->context.dump (f);
437 ipa_print_node_jump_functions_for_edge (f, cs);
441 /* Print ipa_jump_func data structures of all nodes in the call graph to F. */
443 void
444 ipa_print_all_jump_functions (FILE *f)
446 struct cgraph_node *node;
448 fprintf (f, "\nJump functions:\n");
449 FOR_EACH_FUNCTION (node)
451 ipa_print_node_jump_functions (f, node);
455 /* Set jfunc to be a know-really nothing jump function. */
457 static void
458 ipa_set_jf_unknown (struct ipa_jump_func *jfunc)
460 jfunc->type = IPA_JF_UNKNOWN;
461 jfunc->alignment.known = false;
464 /* Set JFUNC to be a copy of another jmp (to be used by jump function
465 combination code). The two functions will share their rdesc. */
467 static void
468 ipa_set_jf_cst_copy (struct ipa_jump_func *dst,
469 struct ipa_jump_func *src)
472 gcc_checking_assert (src->type == IPA_JF_CONST);
473 dst->type = IPA_JF_CONST;
474 dst->value.constant = src->value.constant;
477 /* Set JFUNC to be a constant jmp function. */
479 static void
480 ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
481 struct cgraph_edge *cs)
483 constant = unshare_expr (constant);
484 if (constant && EXPR_P (constant))
485 SET_EXPR_LOCATION (constant, UNKNOWN_LOCATION);
486 jfunc->type = IPA_JF_CONST;
487 jfunc->value.constant.value = unshare_expr_without_location (constant);
489 if (TREE_CODE (constant) == ADDR_EXPR
490 && TREE_CODE (TREE_OPERAND (constant, 0)) == FUNCTION_DECL)
492 struct ipa_cst_ref_desc *rdesc;
493 if (!ipa_refdesc_pool)
494 ipa_refdesc_pool = create_alloc_pool ("IPA-PROP ref descriptions",
495 sizeof (struct ipa_cst_ref_desc), 32);
497 rdesc = (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
498 rdesc->cs = cs;
499 rdesc->next_duplicate = NULL;
500 rdesc->refcount = 1;
501 jfunc->value.constant.rdesc = rdesc;
503 else
504 jfunc->value.constant.rdesc = NULL;
507 /* Set JFUNC to be a simple pass-through jump function. */
508 static void
509 ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
510 bool agg_preserved)
512 jfunc->type = IPA_JF_PASS_THROUGH;
513 jfunc->value.pass_through.operand = NULL_TREE;
514 jfunc->value.pass_through.formal_id = formal_id;
515 jfunc->value.pass_through.operation = NOP_EXPR;
516 jfunc->value.pass_through.agg_preserved = agg_preserved;
519 /* Set JFUNC to be an arithmetic pass through jump function. */
521 static void
522 ipa_set_jf_arith_pass_through (struct ipa_jump_func *jfunc, int formal_id,
523 tree operand, enum tree_code operation)
525 jfunc->type = IPA_JF_PASS_THROUGH;
526 jfunc->value.pass_through.operand = unshare_expr_without_location (operand);
527 jfunc->value.pass_through.formal_id = formal_id;
528 jfunc->value.pass_through.operation = operation;
529 jfunc->value.pass_through.agg_preserved = false;
532 /* Set JFUNC to be an ancestor jump function. */
534 static void
535 ipa_set_ancestor_jf (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
536 int formal_id, bool agg_preserved)
538 jfunc->type = IPA_JF_ANCESTOR;
539 jfunc->value.ancestor.formal_id = formal_id;
540 jfunc->value.ancestor.offset = offset;
541 jfunc->value.ancestor.agg_preserved = agg_preserved;
544 /* Get IPA BB information about the given BB. FBI is the context of analyzis
545 of this function body. */
547 static struct ipa_bb_info *
548 ipa_get_bb_info (struct func_body_info *fbi, basic_block bb)
550 gcc_checking_assert (fbi);
551 return &fbi->bb_infos[bb->index];
554 /* Structure to be passed in between detect_type_change and
555 check_stmt_for_type_change. */
557 struct prop_type_change_info
559 /* Offset into the object where there is the virtual method pointer we are
560 looking for. */
561 HOST_WIDE_INT offset;
562 /* The declaration or SSA_NAME pointer of the base that we are checking for
563 type change. */
564 tree object;
565 /* Set to true if dynamic type change has been detected. */
566 bool type_maybe_changed;
569 /* Return true if STMT can modify a virtual method table pointer.
571 This function makes special assumptions about both constructors and
572 destructors which are all the functions that are allowed to alter the VMT
573 pointers. It assumes that destructors begin with assignment into all VMT
574 pointers and that constructors essentially look in the following way:
576 1) The very first thing they do is that they call constructors of ancestor
577 sub-objects that have them.
579 2) Then VMT pointers of this and all its ancestors is set to new values
580 corresponding to the type corresponding to the constructor.
582 3) Only afterwards, other stuff such as constructor of member sub-objects
583 and the code written by the user is run. Only this may include calling
584 virtual functions, directly or indirectly.
586 There is no way to call a constructor of an ancestor sub-object in any
587 other way.
589 This means that we do not have to care whether constructors get the correct
590 type information because they will always change it (in fact, if we define
591 the type to be given by the VMT pointer, it is undefined).
593 The most important fact to derive from the above is that if, for some
594 statement in the section 3, we try to detect whether the dynamic type has
595 changed, we can safely ignore all calls as we examine the function body
596 backwards until we reach statements in section 2 because these calls cannot
597 be ancestor constructors or destructors (if the input is not bogus) and so
598 do not change the dynamic type (this holds true only for automatically
599 allocated objects but at the moment we devirtualize only these). We then
600 must detect that statements in section 2 change the dynamic type and can try
601 to derive the new type. That is enough and we can stop, we will never see
602 the calls into constructors of sub-objects in this code. Therefore we can
603 safely ignore all call statements that we traverse.
606 static bool
607 stmt_may_be_vtbl_ptr_store (gimple stmt)
609 if (is_gimple_call (stmt))
610 return false;
611 if (gimple_clobber_p (stmt))
612 return false;
613 else if (is_gimple_assign (stmt))
615 tree lhs = gimple_assign_lhs (stmt);
617 if (!AGGREGATE_TYPE_P (TREE_TYPE (lhs)))
619 if (flag_strict_aliasing
620 && !POINTER_TYPE_P (TREE_TYPE (lhs)))
621 return false;
623 if (TREE_CODE (lhs) == COMPONENT_REF
624 && !DECL_VIRTUAL_P (TREE_OPERAND (lhs, 1)))
625 return false;
626 /* In the future we might want to use get_base_ref_and_offset to find
627 if there is a field corresponding to the offset and if so, proceed
628 almost like if it was a component ref. */
631 return true;
634 /* Callback of walk_aliased_vdefs and a helper function for detect_type_change
635 to check whether a particular statement may modify the virtual table
636 pointerIt stores its result into DATA, which points to a
637 prop_type_change_info structure. */
639 static bool
640 check_stmt_for_type_change (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
642 gimple stmt = SSA_NAME_DEF_STMT (vdef);
643 struct prop_type_change_info *tci = (struct prop_type_change_info *) data;
645 if (stmt_may_be_vtbl_ptr_store (stmt))
647 tci->type_maybe_changed = true;
648 return true;
650 else
651 return false;
654 /* See if ARG is PARAM_DECl describing instance passed by pointer
655 or reference in FUNCTION. Return false if the dynamic type may change
656 in between beggining of the function until CALL is invoked.
658 Generally functions are not allowed to change type of such instances,
659 but they call destructors. We assume that methods can not destroy the THIS
660 pointer. Also as a special cases, constructor and destructors may change
661 type of the THIS pointer. */
663 static bool
664 param_type_may_change_p (tree function, tree arg, gimple call)
666 /* Pure functions can not do any changes on the dynamic type;
667 that require writting to memory. */
668 if (flags_from_decl_or_type (function) & (ECF_PURE | ECF_CONST))
669 return false;
670 /* We need to check if we are within inlined consturctor
671 or destructor (ideally we would have way to check that the
672 inline cdtor is actually working on ARG, but we don't have
673 easy tie on this, so punt on all non-pure cdtors.
674 We may also record the types of cdtors and once we know type
675 of the instance match them.
677 Also code unification optimizations may merge calls from
678 different blocks making return values unreliable. So
679 do nothing during late optimization. */
680 if (DECL_STRUCT_FUNCTION (function)->after_inlining)
681 return true;
682 if (TREE_CODE (arg) == SSA_NAME
683 && SSA_NAME_IS_DEFAULT_DEF (arg)
684 && TREE_CODE (SSA_NAME_VAR (arg)) == PARM_DECL)
686 /* Normal (non-THIS) argument. */
687 if ((SSA_NAME_VAR (arg) != DECL_ARGUMENTS (function)
688 || TREE_CODE (TREE_TYPE (function)) != METHOD_TYPE)
689 /* THIS pointer of an method - here we we want to watch constructors
690 and destructors as those definitely may change the dynamic
691 type. */
692 || (TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE
693 && !DECL_CXX_CONSTRUCTOR_P (function)
694 && !DECL_CXX_DESTRUCTOR_P (function)
695 && (SSA_NAME_VAR (arg) == DECL_ARGUMENTS (function))))
697 /* Walk the inline stack and watch out for ctors/dtors. */
698 for (tree block = gimple_block (call); block && TREE_CODE (block) == BLOCK;
699 block = BLOCK_SUPERCONTEXT (block))
700 if (BLOCK_ABSTRACT_ORIGIN (block)
701 && TREE_CODE (BLOCK_ABSTRACT_ORIGIN (block)) == FUNCTION_DECL)
703 tree fn = BLOCK_ABSTRACT_ORIGIN (block);
705 if (flags_from_decl_or_type (fn) & (ECF_PURE | ECF_CONST))
706 continue;
707 if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE
708 && (DECL_CXX_CONSTRUCTOR_P (fn)
709 || DECL_CXX_DESTRUCTOR_P (fn)))
710 return true;
712 return false;
715 return true;
718 /* Detect whether the dynamic type of ARG of COMP_TYPE has changed (before
719 callsite CALL) by looking for assignments to its virtual table pointer. If
720 it is, return true and fill in the jump function JFUNC with relevant type
721 information or set it to unknown. ARG is the object itself (not a pointer
722 to it, unless dereferenced). BASE is the base of the memory access as
723 returned by get_ref_base_and_extent, as is the offset.
725 This is helper function for detect_type_change and detect_type_change_ssa
726 that does the heavy work which is usually unnecesary. */
728 static bool
729 detect_type_change_from_memory_writes (tree arg, tree base, tree comp_type,
730 gcall *call, struct ipa_jump_func *jfunc,
731 HOST_WIDE_INT offset)
733 struct prop_type_change_info tci;
734 ao_ref ao;
735 bool entry_reached = false;
737 gcc_checking_assert (DECL_P (arg)
738 || TREE_CODE (arg) == MEM_REF
739 || handled_component_p (arg));
741 comp_type = TYPE_MAIN_VARIANT (comp_type);
743 /* Const calls cannot call virtual methods through VMT and so type changes do
744 not matter. */
745 if (!flag_devirtualize || !gimple_vuse (call)
746 /* Be sure expected_type is polymorphic. */
747 || !comp_type
748 || TREE_CODE (comp_type) != RECORD_TYPE
749 || !TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type))
750 || !BINFO_VTABLE (TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type))))
751 return true;
753 ao_ref_init (&ao, arg);
754 ao.base = base;
755 ao.offset = offset;
756 ao.size = POINTER_SIZE;
757 ao.max_size = ao.size;
759 tci.offset = offset;
760 tci.object = get_base_address (arg);
761 tci.type_maybe_changed = false;
763 walk_aliased_vdefs (&ao, gimple_vuse (call), check_stmt_for_type_change,
764 &tci, NULL, &entry_reached);
765 if (!tci.type_maybe_changed)
766 return false;
768 ipa_set_jf_unknown (jfunc);
769 return true;
772 /* Detect whether the dynamic type of ARG of COMP_TYPE may have changed.
773 If it is, return true and fill in the jump function JFUNC with relevant type
774 information or set it to unknown. ARG is the object itself (not a pointer
775 to it, unless dereferenced). BASE is the base of the memory access as
776 returned by get_ref_base_and_extent, as is the offset. */
778 static bool
779 detect_type_change (tree arg, tree base, tree comp_type, gcall *call,
780 struct ipa_jump_func *jfunc, HOST_WIDE_INT offset)
782 if (!flag_devirtualize)
783 return false;
785 if (TREE_CODE (base) == MEM_REF
786 && !param_type_may_change_p (current_function_decl,
787 TREE_OPERAND (base, 0),
788 call))
789 return false;
790 return detect_type_change_from_memory_writes (arg, base, comp_type,
791 call, jfunc, offset);
794 /* Like detect_type_change but ARG is supposed to be a non-dereferenced pointer
795 SSA name (its dereference will become the base and the offset is assumed to
796 be zero). */
798 static bool
799 detect_type_change_ssa (tree arg, tree comp_type,
800 gcall *call, struct ipa_jump_func *jfunc)
802 gcc_checking_assert (TREE_CODE (arg) == SSA_NAME);
803 if (!flag_devirtualize
804 || !POINTER_TYPE_P (TREE_TYPE (arg)))
805 return false;
807 if (!param_type_may_change_p (current_function_decl, arg, call))
808 return false;
810 arg = build2 (MEM_REF, ptr_type_node, arg,
811 build_int_cst (ptr_type_node, 0));
813 return detect_type_change_from_memory_writes (arg, arg, comp_type,
814 call, jfunc, 0);
817 /* Callback of walk_aliased_vdefs. Flags that it has been invoked to the
818 boolean variable pointed to by DATA. */
820 static bool
821 mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
822 void *data)
824 bool *b = (bool *) data;
825 *b = true;
826 return true;
829 /* Return true if we have already walked so many statements in AA that we
830 should really just start giving up. */
832 static bool
833 aa_overwalked (struct func_body_info *fbi)
835 gcc_checking_assert (fbi);
836 return fbi->aa_walked > (unsigned) PARAM_VALUE (PARAM_IPA_MAX_AA_STEPS);
839 /* Find the nearest valid aa status for parameter specified by INDEX that
840 dominates BB. */
842 static struct param_aa_status *
843 find_dominating_aa_status (struct func_body_info *fbi, basic_block bb,
844 int index)
846 while (true)
848 bb = get_immediate_dominator (CDI_DOMINATORS, bb);
849 if (!bb)
850 return NULL;
851 struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
852 if (!bi->param_aa_statuses.is_empty ()
853 && bi->param_aa_statuses[index].valid)
854 return &bi->param_aa_statuses[index];
858 /* Get AA status structure for the given BB and parameter with INDEX. Allocate
859 structures and/or intialize the result with a dominating description as
860 necessary. */
862 static struct param_aa_status *
863 parm_bb_aa_status_for_bb (struct func_body_info *fbi, basic_block bb,
864 int index)
866 gcc_checking_assert (fbi);
867 struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
868 if (bi->param_aa_statuses.is_empty ())
869 bi->param_aa_statuses.safe_grow_cleared (fbi->param_count);
870 struct param_aa_status *paa = &bi->param_aa_statuses[index];
871 if (!paa->valid)
873 gcc_checking_assert (!paa->parm_modified
874 && !paa->ref_modified
875 && !paa->pt_modified);
876 struct param_aa_status *dom_paa;
877 dom_paa = find_dominating_aa_status (fbi, bb, index);
878 if (dom_paa)
879 *paa = *dom_paa;
880 else
881 paa->valid = true;
884 return paa;
887 /* Return true if a load from a formal parameter PARM_LOAD is known to retrieve
888 a value known not to be modified in this function before reaching the
889 statement STMT. FBI holds information about the function we have so far
890 gathered but do not survive the summary building stage. */
892 static bool
893 parm_preserved_before_stmt_p (struct func_body_info *fbi, int index,
894 gimple stmt, tree parm_load)
896 struct param_aa_status *paa;
897 bool modified = false;
898 ao_ref refd;
900 /* FIXME: FBI can be NULL if we are being called from outside
901 ipa_node_analysis or ipcp_transform_function, which currently happens
902 during inlining analysis. It would be great to extend fbi's lifetime and
903 always have it. Currently, we are just not afraid of too much walking in
904 that case. */
905 if (fbi)
907 if (aa_overwalked (fbi))
908 return false;
909 paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (stmt), index);
910 if (paa->parm_modified)
911 return false;
913 else
914 paa = NULL;
916 gcc_checking_assert (gimple_vuse (stmt) != NULL_TREE);
917 ao_ref_init (&refd, parm_load);
918 int walked = walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified,
919 &modified, NULL);
920 if (fbi)
921 fbi->aa_walked += walked;
922 if (paa && modified)
923 paa->parm_modified = true;
924 return !modified;
927 /* If STMT is an assignment that loads a value from an parameter declaration,
928 return the index of the parameter in ipa_node_params which has not been
929 modified. Otherwise return -1. */
931 static int
932 load_from_unmodified_param (struct func_body_info *fbi,
933 vec<ipa_param_descriptor> descriptors,
934 gimple stmt)
936 int index;
937 tree op1;
939 if (!gimple_assign_single_p (stmt))
940 return -1;
942 op1 = gimple_assign_rhs1 (stmt);
943 if (TREE_CODE (op1) != PARM_DECL)
944 return -1;
946 index = ipa_get_param_decl_index_1 (descriptors, op1);
947 if (index < 0
948 || !parm_preserved_before_stmt_p (fbi, index, stmt, op1))
949 return -1;
951 return index;
954 /* Return true if memory reference REF (which must be a load through parameter
955 with INDEX) loads data that are known to be unmodified in this function
956 before reaching statement STMT. */
958 static bool
959 parm_ref_data_preserved_p (struct func_body_info *fbi,
960 int index, gimple stmt, tree ref)
962 struct param_aa_status *paa;
963 bool modified = false;
964 ao_ref refd;
966 /* FIXME: FBI can be NULL if we are being called from outside
967 ipa_node_analysis or ipcp_transform_function, which currently happens
968 during inlining analysis. It would be great to extend fbi's lifetime and
969 always have it. Currently, we are just not afraid of too much walking in
970 that case. */
971 if (fbi)
973 if (aa_overwalked (fbi))
974 return false;
975 paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (stmt), index);
976 if (paa->ref_modified)
977 return false;
979 else
980 paa = NULL;
982 gcc_checking_assert (gimple_vuse (stmt));
983 ao_ref_init (&refd, ref);
984 int walked = walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified,
985 &modified, NULL);
986 if (fbi)
987 fbi->aa_walked += walked;
988 if (paa && modified)
989 paa->ref_modified = true;
990 return !modified;
993 /* Return true if the data pointed to by PARM (which is a parameter with INDEX)
994 is known to be unmodified in this function before reaching call statement
995 CALL into which it is passed. FBI describes the function body. */
997 static bool
998 parm_ref_data_pass_through_p (struct func_body_info *fbi, int index,
999 gimple call, tree parm)
1001 bool modified = false;
1002 ao_ref refd;
1004 /* It's unnecessary to calculate anything about memory contnets for a const
1005 function because it is not goin to use it. But do not cache the result
1006 either. Also, no such calculations for non-pointers. */
1007 if (!gimple_vuse (call)
1008 || !POINTER_TYPE_P (TREE_TYPE (parm))
1009 || aa_overwalked (fbi))
1010 return false;
1012 struct param_aa_status *paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (call),
1013 index);
1014 if (paa->pt_modified)
1015 return false;
1017 ao_ref_init_from_ptr_and_size (&refd, parm, NULL_TREE);
1018 int walked = walk_aliased_vdefs (&refd, gimple_vuse (call), mark_modified,
1019 &modified, NULL);
1020 fbi->aa_walked += walked;
1021 if (modified)
1022 paa->pt_modified = true;
1023 return !modified;
1026 /* Return true if we can prove that OP is a memory reference loading unmodified
1027 data from an aggregate passed as a parameter and if the aggregate is passed
1028 by reference, that the alias type of the load corresponds to the type of the
1029 formal parameter (so that we can rely on this type for TBAA in callers).
1030 INFO and PARMS_AINFO describe parameters of the current function (but the
1031 latter can be NULL), STMT is the load statement. If function returns true,
1032 *INDEX_P, *OFFSET_P and *BY_REF is filled with the parameter index, offset
1033 within the aggregate and whether it is a load from a value passed by
1034 reference respectively. */
1036 static bool
1037 ipa_load_from_parm_agg_1 (struct func_body_info *fbi,
1038 vec<ipa_param_descriptor> descriptors,
1039 gimple stmt, tree op, int *index_p,
1040 HOST_WIDE_INT *offset_p, HOST_WIDE_INT *size_p,
1041 bool *by_ref_p)
1043 int index;
1044 HOST_WIDE_INT size, max_size;
1045 tree base = get_ref_base_and_extent (op, offset_p, &size, &max_size);
1047 if (max_size == -1 || max_size != size || *offset_p < 0)
1048 return false;
1050 if (DECL_P (base))
1052 int index = ipa_get_param_decl_index_1 (descriptors, base);
1053 if (index >= 0
1054 && parm_preserved_before_stmt_p (fbi, index, stmt, op))
1056 *index_p = index;
1057 *by_ref_p = false;
1058 if (size_p)
1059 *size_p = size;
1060 return true;
1062 return false;
1065 if (TREE_CODE (base) != MEM_REF
1066 || TREE_CODE (TREE_OPERAND (base, 0)) != SSA_NAME
1067 || !integer_zerop (TREE_OPERAND (base, 1)))
1068 return false;
1070 if (SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (base, 0)))
1072 tree parm = SSA_NAME_VAR (TREE_OPERAND (base, 0));
1073 index = ipa_get_param_decl_index_1 (descriptors, parm);
1075 else
1077 /* This branch catches situations where a pointer parameter is not a
1078 gimple register, for example:
1080 void hip7(S*) (struct S * p)
1082 void (*<T2e4>) (struct S *) D.1867;
1083 struct S * p.1;
1085 <bb 2>:
1086 p.1_1 = p;
1087 D.1867_2 = p.1_1->f;
1088 D.1867_2 ();
1089 gdp = &p;
1092 gimple def = SSA_NAME_DEF_STMT (TREE_OPERAND (base, 0));
1093 index = load_from_unmodified_param (fbi, descriptors, def);
1096 if (index >= 0
1097 && parm_ref_data_preserved_p (fbi, index, stmt, op))
1099 *index_p = index;
1100 *by_ref_p = true;
1101 if (size_p)
1102 *size_p = size;
1103 return true;
1105 return false;
1108 /* Just like the previous function, just without the param_analysis_info
1109 pointer, for users outside of this file. */
1111 bool
1112 ipa_load_from_parm_agg (struct ipa_node_params *info, gimple stmt,
1113 tree op, int *index_p, HOST_WIDE_INT *offset_p,
1114 bool *by_ref_p)
1116 return ipa_load_from_parm_agg_1 (NULL, info->descriptors, stmt, op, index_p,
1117 offset_p, NULL, by_ref_p);
1120 /* Given that an actual argument is an SSA_NAME (given in NAME) and is a result
1121 of an assignment statement STMT, try to determine whether we are actually
1122 handling any of the following cases and construct an appropriate jump
1123 function into JFUNC if so:
1125 1) The passed value is loaded from a formal parameter which is not a gimple
1126 register (most probably because it is addressable, the value has to be
1127 scalar) and we can guarantee the value has not changed. This case can
1128 therefore be described by a simple pass-through jump function. For example:
1130 foo (int a)
1132 int a.0;
1134 a.0_2 = a;
1135 bar (a.0_2);
1137 2) The passed value can be described by a simple arithmetic pass-through
1138 jump function. E.g.
1140 foo (int a)
1142 int D.2064;
1144 D.2064_4 = a.1(D) + 4;
1145 bar (D.2064_4);
1147 This case can also occur in combination of the previous one, e.g.:
1149 foo (int a, int z)
1151 int a.0;
1152 int D.2064;
1154 a.0_3 = a;
1155 D.2064_4 = a.0_3 + 4;
1156 foo (D.2064_4);
1158 3) The passed value is an address of an object within another one (which
1159 also passed by reference). Such situations are described by an ancestor
1160 jump function and describe situations such as:
1162 B::foo() (struct B * const this)
1164 struct A * D.1845;
1166 D.1845_2 = &this_1(D)->D.1748;
1167 A::bar (D.1845_2);
1169 INFO is the structure describing individual parameters access different
1170 stages of IPA optimizations. PARMS_AINFO contains the information that is
1171 only needed for intraprocedural analysis. */
1173 static void
1174 compute_complex_assign_jump_func (struct func_body_info *fbi,
1175 struct ipa_node_params *info,
1176 struct ipa_jump_func *jfunc,
1177 gcall *call, gimple stmt, tree name,
1178 tree param_type)
1180 HOST_WIDE_INT offset, size, max_size;
1181 tree op1, tc_ssa, base, ssa;
1182 int index;
1184 op1 = gimple_assign_rhs1 (stmt);
1186 if (TREE_CODE (op1) == SSA_NAME)
1188 if (SSA_NAME_IS_DEFAULT_DEF (op1))
1189 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (op1));
1190 else
1191 index = load_from_unmodified_param (fbi, info->descriptors,
1192 SSA_NAME_DEF_STMT (op1));
1193 tc_ssa = op1;
1195 else
1197 index = load_from_unmodified_param (fbi, info->descriptors, stmt);
1198 tc_ssa = gimple_assign_lhs (stmt);
1201 if (index >= 0)
1203 tree op2 = gimple_assign_rhs2 (stmt);
1205 if (op2)
1207 if (!is_gimple_ip_invariant (op2)
1208 || (TREE_CODE_CLASS (gimple_expr_code (stmt)) != tcc_comparison
1209 && !useless_type_conversion_p (TREE_TYPE (name),
1210 TREE_TYPE (op1))))
1211 return;
1213 ipa_set_jf_arith_pass_through (jfunc, index, op2,
1214 gimple_assign_rhs_code (stmt));
1216 else if (gimple_assign_single_p (stmt))
1218 bool agg_p = parm_ref_data_pass_through_p (fbi, index, call, tc_ssa);
1219 ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
1221 return;
1224 if (TREE_CODE (op1) != ADDR_EXPR)
1225 return;
1226 op1 = TREE_OPERAND (op1, 0);
1227 if (TREE_CODE (TREE_TYPE (op1)) != RECORD_TYPE)
1228 return;
1229 base = get_ref_base_and_extent (op1, &offset, &size, &max_size);
1230 if (TREE_CODE (base) != MEM_REF
1231 /* If this is a varying address, punt. */
1232 || max_size == -1
1233 || max_size != size)
1234 return;
1235 offset += mem_ref_offset (base).to_short_addr () * BITS_PER_UNIT;
1236 ssa = TREE_OPERAND (base, 0);
1237 if (TREE_CODE (ssa) != SSA_NAME
1238 || !SSA_NAME_IS_DEFAULT_DEF (ssa)
1239 || offset < 0)
1240 return;
1242 /* Dynamic types are changed in constructors and destructors. */
1243 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (ssa));
1244 if (index >= 0 && param_type && POINTER_TYPE_P (param_type))
1245 ipa_set_ancestor_jf (jfunc, offset, index,
1246 parm_ref_data_pass_through_p (fbi, index, call, ssa));
1249 /* Extract the base, offset and MEM_REF expression from a statement ASSIGN if
1250 it looks like:
1252 iftmp.1_3 = &obj_2(D)->D.1762;
1254 The base of the MEM_REF must be a default definition SSA NAME of a
1255 parameter. Return NULL_TREE if it looks otherwise. If case of success, the
1256 whole MEM_REF expression is returned and the offset calculated from any
1257 handled components and the MEM_REF itself is stored into *OFFSET. The whole
1258 RHS stripped off the ADDR_EXPR is stored into *OBJ_P. */
1260 static tree
1261 get_ancestor_addr_info (gimple assign, tree *obj_p, HOST_WIDE_INT *offset)
1263 HOST_WIDE_INT size, max_size;
1264 tree expr, parm, obj;
1266 if (!gimple_assign_single_p (assign))
1267 return NULL_TREE;
1268 expr = gimple_assign_rhs1 (assign);
1270 if (TREE_CODE (expr) != ADDR_EXPR)
1271 return NULL_TREE;
1272 expr = TREE_OPERAND (expr, 0);
1273 obj = expr;
1274 expr = get_ref_base_and_extent (expr, offset, &size, &max_size);
1276 if (TREE_CODE (expr) != MEM_REF
1277 /* If this is a varying address, punt. */
1278 || max_size == -1
1279 || max_size != size
1280 || *offset < 0)
1281 return NULL_TREE;
1282 parm = TREE_OPERAND (expr, 0);
1283 if (TREE_CODE (parm) != SSA_NAME
1284 || !SSA_NAME_IS_DEFAULT_DEF (parm)
1285 || TREE_CODE (SSA_NAME_VAR (parm)) != PARM_DECL)
1286 return NULL_TREE;
1288 *offset += mem_ref_offset (expr).to_short_addr () * BITS_PER_UNIT;
1289 *obj_p = obj;
1290 return expr;
1294 /* Given that an actual argument is an SSA_NAME that is a result of a phi
1295 statement PHI, try to find out whether NAME is in fact a
1296 multiple-inheritance typecast from a descendant into an ancestor of a formal
1297 parameter and thus can be described by an ancestor jump function and if so,
1298 write the appropriate function into JFUNC.
1300 Essentially we want to match the following pattern:
1302 if (obj_2(D) != 0B)
1303 goto <bb 3>;
1304 else
1305 goto <bb 4>;
1307 <bb 3>:
1308 iftmp.1_3 = &obj_2(D)->D.1762;
1310 <bb 4>:
1311 # iftmp.1_1 = PHI <iftmp.1_3(3), 0B(2)>
1312 D.1879_6 = middleman_1 (iftmp.1_1, i_5(D));
1313 return D.1879_6; */
1315 static void
1316 compute_complex_ancestor_jump_func (struct func_body_info *fbi,
1317 struct ipa_node_params *info,
1318 struct ipa_jump_func *jfunc,
1319 gcall *call, gphi *phi)
1321 HOST_WIDE_INT offset;
1322 gimple assign, cond;
1323 basic_block phi_bb, assign_bb, cond_bb;
1324 tree tmp, parm, expr, obj;
1325 int index, i;
1327 if (gimple_phi_num_args (phi) != 2)
1328 return;
1330 if (integer_zerop (PHI_ARG_DEF (phi, 1)))
1331 tmp = PHI_ARG_DEF (phi, 0);
1332 else if (integer_zerop (PHI_ARG_DEF (phi, 0)))
1333 tmp = PHI_ARG_DEF (phi, 1);
1334 else
1335 return;
1336 if (TREE_CODE (tmp) != SSA_NAME
1337 || SSA_NAME_IS_DEFAULT_DEF (tmp)
1338 || !POINTER_TYPE_P (TREE_TYPE (tmp))
1339 || TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) != RECORD_TYPE)
1340 return;
1342 assign = SSA_NAME_DEF_STMT (tmp);
1343 assign_bb = gimple_bb (assign);
1344 if (!single_pred_p (assign_bb))
1345 return;
1346 expr = get_ancestor_addr_info (assign, &obj, &offset);
1347 if (!expr)
1348 return;
1349 parm = TREE_OPERAND (expr, 0);
1350 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (parm));
1351 if (index < 0)
1352 return;
1354 cond_bb = single_pred (assign_bb);
1355 cond = last_stmt (cond_bb);
1356 if (!cond
1357 || gimple_code (cond) != GIMPLE_COND
1358 || gimple_cond_code (cond) != NE_EXPR
1359 || gimple_cond_lhs (cond) != parm
1360 || !integer_zerop (gimple_cond_rhs (cond)))
1361 return;
1363 phi_bb = gimple_bb (phi);
1364 for (i = 0; i < 2; i++)
1366 basic_block pred = EDGE_PRED (phi_bb, i)->src;
1367 if (pred != assign_bb && pred != cond_bb)
1368 return;
1371 ipa_set_ancestor_jf (jfunc, offset, index,
1372 parm_ref_data_pass_through_p (fbi, index, call, parm));
1375 /* Inspect the given TYPE and return true iff it has the same structure (the
1376 same number of fields of the same types) as a C++ member pointer. If
1377 METHOD_PTR and DELTA are non-NULL, store the trees representing the
1378 corresponding fields there. */
1380 static bool
1381 type_like_member_ptr_p (tree type, tree *method_ptr, tree *delta)
1383 tree fld;
1385 if (TREE_CODE (type) != RECORD_TYPE)
1386 return false;
1388 fld = TYPE_FIELDS (type);
1389 if (!fld || !POINTER_TYPE_P (TREE_TYPE (fld))
1390 || TREE_CODE (TREE_TYPE (TREE_TYPE (fld))) != METHOD_TYPE
1391 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
1392 return false;
1394 if (method_ptr)
1395 *method_ptr = fld;
1397 fld = DECL_CHAIN (fld);
1398 if (!fld || INTEGRAL_TYPE_P (fld)
1399 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
1400 return false;
1401 if (delta)
1402 *delta = fld;
1404 if (DECL_CHAIN (fld))
1405 return false;
1407 return true;
1410 /* If RHS is an SSA_NAME and it is defined by a simple copy assign statement,
1411 return the rhs of its defining statement. Otherwise return RHS as it
1412 is. */
1414 static inline tree
1415 get_ssa_def_if_simple_copy (tree rhs)
1417 while (TREE_CODE (rhs) == SSA_NAME && !SSA_NAME_IS_DEFAULT_DEF (rhs))
1419 gimple def_stmt = SSA_NAME_DEF_STMT (rhs);
1421 if (gimple_assign_single_p (def_stmt))
1422 rhs = gimple_assign_rhs1 (def_stmt);
1423 else
1424 break;
1426 return rhs;
1429 /* Simple linked list, describing known contents of an aggregate beforere
1430 call. */
1432 struct ipa_known_agg_contents_list
1434 /* Offset and size of the described part of the aggregate. */
1435 HOST_WIDE_INT offset, size;
1436 /* Known constant value or NULL if the contents is known to be unknown. */
1437 tree constant;
1438 /* Pointer to the next structure in the list. */
1439 struct ipa_known_agg_contents_list *next;
1442 /* Find the proper place in linked list of ipa_known_agg_contents_list
1443 structures where to put a new one with the given LHS_OFFSET and LHS_SIZE,
1444 unless there is a partial overlap, in which case return NULL, or such
1445 element is already there, in which case set *ALREADY_THERE to true. */
1447 static struct ipa_known_agg_contents_list **
1448 get_place_in_agg_contents_list (struct ipa_known_agg_contents_list **list,
1449 HOST_WIDE_INT lhs_offset,
1450 HOST_WIDE_INT lhs_size,
1451 bool *already_there)
1453 struct ipa_known_agg_contents_list **p = list;
1454 while (*p && (*p)->offset < lhs_offset)
1456 if ((*p)->offset + (*p)->size > lhs_offset)
1457 return NULL;
1458 p = &(*p)->next;
1461 if (*p && (*p)->offset < lhs_offset + lhs_size)
1463 if ((*p)->offset == lhs_offset && (*p)->size == lhs_size)
1464 /* We already know this value is subsequently overwritten with
1465 something else. */
1466 *already_there = true;
1467 else
1468 /* Otherwise this is a partial overlap which we cannot
1469 represent. */
1470 return NULL;
1472 return p;
1475 /* Build aggregate jump function from LIST, assuming there are exactly
1476 CONST_COUNT constant entries there and that th offset of the passed argument
1477 is ARG_OFFSET and store it into JFUNC. */
1479 static void
1480 build_agg_jump_func_from_list (struct ipa_known_agg_contents_list *list,
1481 int const_count, HOST_WIDE_INT arg_offset,
1482 struct ipa_jump_func *jfunc)
1484 vec_alloc (jfunc->agg.items, const_count);
1485 while (list)
1487 if (list->constant)
1489 struct ipa_agg_jf_item item;
1490 item.offset = list->offset - arg_offset;
1491 gcc_assert ((item.offset % BITS_PER_UNIT) == 0);
1492 item.value = unshare_expr_without_location (list->constant);
1493 jfunc->agg.items->quick_push (item);
1495 list = list->next;
1499 /* Traverse statements from CALL backwards, scanning whether an aggregate given
1500 in ARG is filled in with constant values. ARG can either be an aggregate
1501 expression or a pointer to an aggregate. ARG_TYPE is the type of the
1502 aggregate. JFUNC is the jump function into which the constants are
1503 subsequently stored. */
1505 static void
1506 determine_locally_known_aggregate_parts (gcall *call, tree arg,
1507 tree arg_type,
1508 struct ipa_jump_func *jfunc)
1510 struct ipa_known_agg_contents_list *list = NULL;
1511 int item_count = 0, const_count = 0;
1512 HOST_WIDE_INT arg_offset, arg_size;
1513 gimple_stmt_iterator gsi;
1514 tree arg_base;
1515 bool check_ref, by_ref;
1516 ao_ref r;
1518 /* The function operates in three stages. First, we prepare check_ref, r,
1519 arg_base and arg_offset based on what is actually passed as an actual
1520 argument. */
1522 if (POINTER_TYPE_P (arg_type))
1524 by_ref = true;
1525 if (TREE_CODE (arg) == SSA_NAME)
1527 tree type_size;
1528 if (!tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (arg_type))))
1529 return;
1530 check_ref = true;
1531 arg_base = arg;
1532 arg_offset = 0;
1533 type_size = TYPE_SIZE (TREE_TYPE (arg_type));
1534 arg_size = tree_to_uhwi (type_size);
1535 ao_ref_init_from_ptr_and_size (&r, arg_base, NULL_TREE);
1537 else if (TREE_CODE (arg) == ADDR_EXPR)
1539 HOST_WIDE_INT arg_max_size;
1541 arg = TREE_OPERAND (arg, 0);
1542 arg_base = get_ref_base_and_extent (arg, &arg_offset, &arg_size,
1543 &arg_max_size);
1544 if (arg_max_size == -1
1545 || arg_max_size != arg_size
1546 || arg_offset < 0)
1547 return;
1548 if (DECL_P (arg_base))
1550 check_ref = false;
1551 ao_ref_init (&r, arg_base);
1553 else
1554 return;
1556 else
1557 return;
1559 else
1561 HOST_WIDE_INT arg_max_size;
1563 gcc_checking_assert (AGGREGATE_TYPE_P (TREE_TYPE (arg)));
1565 by_ref = false;
1566 check_ref = false;
1567 arg_base = get_ref_base_and_extent (arg, &arg_offset, &arg_size,
1568 &arg_max_size);
1569 if (arg_max_size == -1
1570 || arg_max_size != arg_size
1571 || arg_offset < 0)
1572 return;
1574 ao_ref_init (&r, arg);
1577 /* Second stage walks back the BB, looks at individual statements and as long
1578 as it is confident of how the statements affect contents of the
1579 aggregates, it builds a sorted linked list of ipa_agg_jf_list structures
1580 describing it. */
1581 gsi = gsi_for_stmt (call);
1582 gsi_prev (&gsi);
1583 for (; !gsi_end_p (gsi); gsi_prev (&gsi))
1585 struct ipa_known_agg_contents_list *n, **p;
1586 gimple stmt = gsi_stmt (gsi);
1587 HOST_WIDE_INT lhs_offset, lhs_size, lhs_max_size;
1588 tree lhs, rhs, lhs_base;
1590 if (!stmt_may_clobber_ref_p_1 (stmt, &r))
1591 continue;
1592 if (!gimple_assign_single_p (stmt))
1593 break;
1595 lhs = gimple_assign_lhs (stmt);
1596 rhs = gimple_assign_rhs1 (stmt);
1597 if (!is_gimple_reg_type (TREE_TYPE (rhs))
1598 || TREE_CODE (lhs) == BIT_FIELD_REF
1599 || contains_bitfld_component_ref_p (lhs))
1600 break;
1602 lhs_base = get_ref_base_and_extent (lhs, &lhs_offset, &lhs_size,
1603 &lhs_max_size);
1604 if (lhs_max_size == -1
1605 || lhs_max_size != lhs_size)
1606 break;
1608 if (check_ref)
1610 if (TREE_CODE (lhs_base) != MEM_REF
1611 || TREE_OPERAND (lhs_base, 0) != arg_base
1612 || !integer_zerop (TREE_OPERAND (lhs_base, 1)))
1613 break;
1615 else if (lhs_base != arg_base)
1617 if (DECL_P (lhs_base))
1618 continue;
1619 else
1620 break;
1623 bool already_there = false;
1624 p = get_place_in_agg_contents_list (&list, lhs_offset, lhs_size,
1625 &already_there);
1626 if (!p)
1627 break;
1628 if (already_there)
1629 continue;
1631 rhs = get_ssa_def_if_simple_copy (rhs);
1632 n = XALLOCA (struct ipa_known_agg_contents_list);
1633 n->size = lhs_size;
1634 n->offset = lhs_offset;
1635 if (is_gimple_ip_invariant (rhs))
1637 n->constant = rhs;
1638 const_count++;
1640 else
1641 n->constant = NULL_TREE;
1642 n->next = *p;
1643 *p = n;
1645 item_count++;
1646 if (const_count == PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS)
1647 || item_count == 2 * PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS))
1648 break;
1651 /* Third stage just goes over the list and creates an appropriate vector of
1652 ipa_agg_jf_item structures out of it, of sourse only if there are
1653 any known constants to begin with. */
1655 if (const_count)
1657 jfunc->agg.by_ref = by_ref;
1658 build_agg_jump_func_from_list (list, const_count, arg_offset, jfunc);
1662 static tree
1663 ipa_get_callee_param_type (struct cgraph_edge *e, int i)
1665 int n;
1666 tree type = (e->callee
1667 ? TREE_TYPE (e->callee->decl)
1668 : gimple_call_fntype (e->call_stmt));
1669 tree t = TYPE_ARG_TYPES (type);
1671 for (n = 0; n < i; n++)
1673 if (!t)
1674 break;
1675 t = TREE_CHAIN (t);
1677 if (t)
1678 return TREE_VALUE (t);
1679 if (!e->callee)
1680 return NULL;
1681 t = DECL_ARGUMENTS (e->callee->decl);
1682 for (n = 0; n < i; n++)
1684 if (!t)
1685 return NULL;
1686 t = TREE_CHAIN (t);
1688 if (t)
1689 return TREE_TYPE (t);
1690 return NULL;
1693 /* Compute jump function for all arguments of callsite CS and insert the
1694 information in the jump_functions array in the ipa_edge_args corresponding
1695 to this callsite. */
1697 static void
1698 ipa_compute_jump_functions_for_edge (struct func_body_info *fbi,
1699 struct cgraph_edge *cs)
1701 struct ipa_node_params *info = IPA_NODE_REF (cs->caller);
1702 struct ipa_edge_args *args = IPA_EDGE_REF (cs);
1703 gcall *call = cs->call_stmt;
1704 int n, arg_num = gimple_call_num_args (call);
1705 bool useful_context = false;
1707 if (arg_num == 0 || args->jump_functions)
1708 return;
1709 vec_safe_grow_cleared (args->jump_functions, arg_num);
1710 if (flag_devirtualize)
1711 vec_safe_grow_cleared (args->polymorphic_call_contexts, arg_num);
1713 if (gimple_call_internal_p (call))
1714 return;
1715 if (ipa_func_spec_opts_forbid_analysis_p (cs->caller))
1716 return;
1718 for (n = 0; n < arg_num; n++)
1720 struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, n);
1721 tree arg = gimple_call_arg (call, n);
1722 tree param_type = ipa_get_callee_param_type (cs, n);
1723 if (flag_devirtualize && POINTER_TYPE_P (TREE_TYPE (arg)))
1725 tree instance;
1726 struct ipa_polymorphic_call_context context (cs->caller->decl,
1727 arg, cs->call_stmt,
1728 &instance);
1729 context.get_dynamic_type (instance, arg, NULL, cs->call_stmt);
1730 *ipa_get_ith_polymorhic_call_context (args, n) = context;
1731 if (!context.useless_p ())
1732 useful_context = true;
1735 if (POINTER_TYPE_P (TREE_TYPE(arg)))
1737 unsigned HOST_WIDE_INT hwi_bitpos;
1738 unsigned align;
1740 if (get_pointer_alignment_1 (arg, &align, &hwi_bitpos)
1741 && align % BITS_PER_UNIT == 0
1742 && hwi_bitpos % BITS_PER_UNIT == 0)
1744 jfunc->alignment.known = true;
1745 jfunc->alignment.align = align / BITS_PER_UNIT;
1746 jfunc->alignment.misalign = hwi_bitpos / BITS_PER_UNIT;
1748 else
1749 gcc_assert (!jfunc->alignment.known);
1751 else
1752 gcc_assert (!jfunc->alignment.known);
1754 if (is_gimple_ip_invariant (arg))
1755 ipa_set_jf_constant (jfunc, arg, cs);
1756 else if (!is_gimple_reg_type (TREE_TYPE (arg))
1757 && TREE_CODE (arg) == PARM_DECL)
1759 int index = ipa_get_param_decl_index (info, arg);
1761 gcc_assert (index >=0);
1762 /* Aggregate passed by value, check for pass-through, otherwise we
1763 will attempt to fill in aggregate contents later in this
1764 for cycle. */
1765 if (parm_preserved_before_stmt_p (fbi, index, call, arg))
1767 ipa_set_jf_simple_pass_through (jfunc, index, false);
1768 continue;
1771 else if (TREE_CODE (arg) == SSA_NAME)
1773 if (SSA_NAME_IS_DEFAULT_DEF (arg))
1775 int index = ipa_get_param_decl_index (info, SSA_NAME_VAR (arg));
1776 if (index >= 0)
1778 bool agg_p;
1779 agg_p = parm_ref_data_pass_through_p (fbi, index, call, arg);
1780 ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
1783 else
1785 gimple stmt = SSA_NAME_DEF_STMT (arg);
1786 if (is_gimple_assign (stmt))
1787 compute_complex_assign_jump_func (fbi, info, jfunc,
1788 call, stmt, arg, param_type);
1789 else if (gimple_code (stmt) == GIMPLE_PHI)
1790 compute_complex_ancestor_jump_func (fbi, info, jfunc,
1791 call,
1792 as_a <gphi *> (stmt));
1796 /* If ARG is pointer, we can not use its type to determine the type of aggregate
1797 passed (because type conversions are ignored in gimple). Usually we can
1798 safely get type from function declaration, but in case of K&R prototypes or
1799 variadic functions we can try our luck with type of the pointer passed.
1800 TODO: Since we look for actual initialization of the memory object, we may better
1801 work out the type based on the memory stores we find. */
1802 if (!param_type)
1803 param_type = TREE_TYPE (arg);
1805 if ((jfunc->type != IPA_JF_PASS_THROUGH
1806 || !ipa_get_jf_pass_through_agg_preserved (jfunc))
1807 && (jfunc->type != IPA_JF_ANCESTOR
1808 || !ipa_get_jf_ancestor_agg_preserved (jfunc))
1809 && (AGGREGATE_TYPE_P (TREE_TYPE (arg))
1810 || POINTER_TYPE_P (param_type)))
1811 determine_locally_known_aggregate_parts (call, arg, param_type, jfunc);
1813 if (!useful_context)
1814 vec_free (args->polymorphic_call_contexts);
1817 /* Compute jump functions for all edges - both direct and indirect - outgoing
1818 from BB. */
1820 static void
1821 ipa_compute_jump_functions_for_bb (struct func_body_info *fbi, basic_block bb)
1823 struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
1824 int i;
1825 struct cgraph_edge *cs;
1827 FOR_EACH_VEC_ELT_REVERSE (bi->cg_edges, i, cs)
1829 struct cgraph_node *callee = cs->callee;
1831 if (callee)
1833 callee->ultimate_alias_target ();
1834 /* We do not need to bother analyzing calls to unknown functions
1835 unless they may become known during lto/whopr. */
1836 if (!callee->definition && !flag_lto)
1837 continue;
1839 ipa_compute_jump_functions_for_edge (fbi, cs);
1843 /* If STMT looks like a statement loading a value from a member pointer formal
1844 parameter, return that parameter and store the offset of the field to
1845 *OFFSET_P, if it is non-NULL. Otherwise return NULL (but *OFFSET_P still
1846 might be clobbered). If USE_DELTA, then we look for a use of the delta
1847 field rather than the pfn. */
1849 static tree
1850 ipa_get_stmt_member_ptr_load_param (gimple stmt, bool use_delta,
1851 HOST_WIDE_INT *offset_p)
1853 tree rhs, rec, ref_field, ref_offset, fld, ptr_field, delta_field;
1855 if (!gimple_assign_single_p (stmt))
1856 return NULL_TREE;
1858 rhs = gimple_assign_rhs1 (stmt);
1859 if (TREE_CODE (rhs) == COMPONENT_REF)
1861 ref_field = TREE_OPERAND (rhs, 1);
1862 rhs = TREE_OPERAND (rhs, 0);
1864 else
1865 ref_field = NULL_TREE;
1866 if (TREE_CODE (rhs) != MEM_REF)
1867 return NULL_TREE;
1868 rec = TREE_OPERAND (rhs, 0);
1869 if (TREE_CODE (rec) != ADDR_EXPR)
1870 return NULL_TREE;
1871 rec = TREE_OPERAND (rec, 0);
1872 if (TREE_CODE (rec) != PARM_DECL
1873 || !type_like_member_ptr_p (TREE_TYPE (rec), &ptr_field, &delta_field))
1874 return NULL_TREE;
1875 ref_offset = TREE_OPERAND (rhs, 1);
1877 if (use_delta)
1878 fld = delta_field;
1879 else
1880 fld = ptr_field;
1881 if (offset_p)
1882 *offset_p = int_bit_position (fld);
1884 if (ref_field)
1886 if (integer_nonzerop (ref_offset))
1887 return NULL_TREE;
1888 return ref_field == fld ? rec : NULL_TREE;
1890 else
1891 return tree_int_cst_equal (byte_position (fld), ref_offset) ? rec
1892 : NULL_TREE;
1895 /* Returns true iff T is an SSA_NAME defined by a statement. */
1897 static bool
1898 ipa_is_ssa_with_stmt_def (tree t)
1900 if (TREE_CODE (t) == SSA_NAME
1901 && !SSA_NAME_IS_DEFAULT_DEF (t))
1902 return true;
1903 else
1904 return false;
1907 /* Find the indirect call graph edge corresponding to STMT and mark it as a
1908 call to a parameter number PARAM_INDEX. NODE is the caller. Return the
1909 indirect call graph edge. */
1911 static struct cgraph_edge *
1912 ipa_note_param_call (struct cgraph_node *node, int param_index,
1913 gcall *stmt)
1915 struct cgraph_edge *cs;
1917 cs = node->get_edge (stmt);
1918 cs->indirect_info->param_index = param_index;
1919 cs->indirect_info->agg_contents = 0;
1920 cs->indirect_info->member_ptr = 0;
1921 return cs;
1924 /* Analyze the CALL and examine uses of formal parameters of the caller NODE
1925 (described by INFO). PARMS_AINFO is a pointer to a vector containing
1926 intermediate information about each formal parameter. Currently it checks
1927 whether the call calls a pointer that is a formal parameter and if so, the
1928 parameter is marked with the called flag and an indirect call graph edge
1929 describing the call is created. This is very simple for ordinary pointers
1930 represented in SSA but not-so-nice when it comes to member pointers. The
1931 ugly part of this function does nothing more than trying to match the
1932 pattern of such a call. An example of such a pattern is the gimple dump
1933 below, the call is on the last line:
1935 <bb 2>:
1936 f$__delta_5 = f.__delta;
1937 f$__pfn_24 = f.__pfn;
1940 <bb 2>:
1941 f$__delta_5 = MEM[(struct *)&f];
1942 f$__pfn_24 = MEM[(struct *)&f + 4B];
1944 and a few lines below:
1946 <bb 5>
1947 D.2496_3 = (int) f$__pfn_24;
1948 D.2497_4 = D.2496_3 & 1;
1949 if (D.2497_4 != 0)
1950 goto <bb 3>;
1951 else
1952 goto <bb 4>;
1954 <bb 6>:
1955 D.2500_7 = (unsigned int) f$__delta_5;
1956 D.2501_8 = &S + D.2500_7;
1957 D.2502_9 = (int (*__vtbl_ptr_type) (void) * *) D.2501_8;
1958 D.2503_10 = *D.2502_9;
1959 D.2504_12 = f$__pfn_24 + -1;
1960 D.2505_13 = (unsigned int) D.2504_12;
1961 D.2506_14 = D.2503_10 + D.2505_13;
1962 D.2507_15 = *D.2506_14;
1963 iftmp.11_16 = (String:: *) D.2507_15;
1965 <bb 7>:
1966 # iftmp.11_1 = PHI <iftmp.11_16(3), f$__pfn_24(2)>
1967 D.2500_19 = (unsigned int) f$__delta_5;
1968 D.2508_20 = &S + D.2500_19;
1969 D.2493_21 = iftmp.11_1 (D.2508_20, 4);
1971 Such patterns are results of simple calls to a member pointer:
1973 int doprinting (int (MyString::* f)(int) const)
1975 MyString S ("somestring");
1977 return (S.*f)(4);
1980 Moreover, the function also looks for called pointers loaded from aggregates
1981 passed by value or reference. */
1983 static void
1984 ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gcall *call,
1985 tree target)
1987 struct ipa_node_params *info = fbi->info;
1988 HOST_WIDE_INT offset;
1989 bool by_ref;
1991 if (SSA_NAME_IS_DEFAULT_DEF (target))
1993 tree var = SSA_NAME_VAR (target);
1994 int index = ipa_get_param_decl_index (info, var);
1995 if (index >= 0)
1996 ipa_note_param_call (fbi->node, index, call);
1997 return;
2000 int index;
2001 gimple def = SSA_NAME_DEF_STMT (target);
2002 if (gimple_assign_single_p (def)
2003 && ipa_load_from_parm_agg_1 (fbi, info->descriptors, def,
2004 gimple_assign_rhs1 (def), &index, &offset,
2005 NULL, &by_ref))
2007 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
2008 cs->indirect_info->offset = offset;
2009 cs->indirect_info->agg_contents = 1;
2010 cs->indirect_info->by_ref = by_ref;
2011 return;
2014 /* Now we need to try to match the complex pattern of calling a member
2015 pointer. */
2016 if (gimple_code (def) != GIMPLE_PHI
2017 || gimple_phi_num_args (def) != 2
2018 || !POINTER_TYPE_P (TREE_TYPE (target))
2019 || TREE_CODE (TREE_TYPE (TREE_TYPE (target))) != METHOD_TYPE)
2020 return;
2022 /* First, we need to check whether one of these is a load from a member
2023 pointer that is a parameter to this function. */
2024 tree n1 = PHI_ARG_DEF (def, 0);
2025 tree n2 = PHI_ARG_DEF (def, 1);
2026 if (!ipa_is_ssa_with_stmt_def (n1) || !ipa_is_ssa_with_stmt_def (n2))
2027 return;
2028 gimple d1 = SSA_NAME_DEF_STMT (n1);
2029 gimple d2 = SSA_NAME_DEF_STMT (n2);
2031 tree rec;
2032 basic_block bb, virt_bb;
2033 basic_block join = gimple_bb (def);
2034 if ((rec = ipa_get_stmt_member_ptr_load_param (d1, false, &offset)))
2036 if (ipa_get_stmt_member_ptr_load_param (d2, false, NULL))
2037 return;
2039 bb = EDGE_PRED (join, 0)->src;
2040 virt_bb = gimple_bb (d2);
2042 else if ((rec = ipa_get_stmt_member_ptr_load_param (d2, false, &offset)))
2044 bb = EDGE_PRED (join, 1)->src;
2045 virt_bb = gimple_bb (d1);
2047 else
2048 return;
2050 /* Second, we need to check that the basic blocks are laid out in the way
2051 corresponding to the pattern. */
2053 if (!single_pred_p (virt_bb) || !single_succ_p (virt_bb)
2054 || single_pred (virt_bb) != bb
2055 || single_succ (virt_bb) != join)
2056 return;
2058 /* Third, let's see that the branching is done depending on the least
2059 significant bit of the pfn. */
2061 gimple branch = last_stmt (bb);
2062 if (!branch || gimple_code (branch) != GIMPLE_COND)
2063 return;
2065 if ((gimple_cond_code (branch) != NE_EXPR
2066 && gimple_cond_code (branch) != EQ_EXPR)
2067 || !integer_zerop (gimple_cond_rhs (branch)))
2068 return;
2070 tree cond = gimple_cond_lhs (branch);
2071 if (!ipa_is_ssa_with_stmt_def (cond))
2072 return;
2074 def = SSA_NAME_DEF_STMT (cond);
2075 if (!is_gimple_assign (def)
2076 || gimple_assign_rhs_code (def) != BIT_AND_EXPR
2077 || !integer_onep (gimple_assign_rhs2 (def)))
2078 return;
2080 cond = gimple_assign_rhs1 (def);
2081 if (!ipa_is_ssa_with_stmt_def (cond))
2082 return;
2084 def = SSA_NAME_DEF_STMT (cond);
2086 if (is_gimple_assign (def)
2087 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
2089 cond = gimple_assign_rhs1 (def);
2090 if (!ipa_is_ssa_with_stmt_def (cond))
2091 return;
2092 def = SSA_NAME_DEF_STMT (cond);
2095 tree rec2;
2096 rec2 = ipa_get_stmt_member_ptr_load_param (def,
2097 (TARGET_PTRMEMFUNC_VBIT_LOCATION
2098 == ptrmemfunc_vbit_in_delta),
2099 NULL);
2100 if (rec != rec2)
2101 return;
2103 index = ipa_get_param_decl_index (info, rec);
2104 if (index >= 0
2105 && parm_preserved_before_stmt_p (fbi, index, call, rec))
2107 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
2108 cs->indirect_info->offset = offset;
2109 cs->indirect_info->agg_contents = 1;
2110 cs->indirect_info->member_ptr = 1;
2113 return;
2116 /* Analyze a CALL to an OBJ_TYPE_REF which is passed in TARGET and if the
2117 object referenced in the expression is a formal parameter of the caller
2118 FBI->node (described by FBI->info), create a call note for the
2119 statement. */
2121 static void
2122 ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
2123 gcall *call, tree target)
2125 tree obj = OBJ_TYPE_REF_OBJECT (target);
2126 int index;
2127 HOST_WIDE_INT anc_offset;
2129 if (!flag_devirtualize)
2130 return;
2132 if (TREE_CODE (obj) != SSA_NAME)
2133 return;
2135 struct ipa_node_params *info = fbi->info;
2136 if (SSA_NAME_IS_DEFAULT_DEF (obj))
2138 struct ipa_jump_func jfunc;
2139 if (TREE_CODE (SSA_NAME_VAR (obj)) != PARM_DECL)
2140 return;
2142 anc_offset = 0;
2143 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (obj));
2144 gcc_assert (index >= 0);
2145 if (detect_type_change_ssa (obj, obj_type_ref_class (target),
2146 call, &jfunc))
2147 return;
2149 else
2151 struct ipa_jump_func jfunc;
2152 gimple stmt = SSA_NAME_DEF_STMT (obj);
2153 tree expr;
2155 expr = get_ancestor_addr_info (stmt, &obj, &anc_offset);
2156 if (!expr)
2157 return;
2158 index = ipa_get_param_decl_index (info,
2159 SSA_NAME_VAR (TREE_OPERAND (expr, 0)));
2160 gcc_assert (index >= 0);
2161 if (detect_type_change (obj, expr, obj_type_ref_class (target),
2162 call, &jfunc, anc_offset))
2163 return;
2166 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
2167 struct cgraph_indirect_call_info *ii = cs->indirect_info;
2168 ii->offset = anc_offset;
2169 ii->otr_token = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target));
2170 ii->otr_type = obj_type_ref_class (target);
2171 ii->polymorphic = 1;
2174 /* Analyze a call statement CALL whether and how it utilizes formal parameters
2175 of the caller (described by INFO). PARMS_AINFO is a pointer to a vector
2176 containing intermediate information about each formal parameter. */
2178 static void
2179 ipa_analyze_call_uses (struct func_body_info *fbi, gcall *call)
2181 tree target = gimple_call_fn (call);
2183 if (!target
2184 || (TREE_CODE (target) != SSA_NAME
2185 && !virtual_method_call_p (target)))
2186 return;
2188 struct cgraph_edge *cs = fbi->node->get_edge (call);
2189 /* If we previously turned the call into a direct call, there is
2190 no need to analyze. */
2191 if (cs && !cs->indirect_unknown_callee)
2192 return;
2194 if (cs->indirect_info->polymorphic && flag_devirtualize)
2196 tree instance;
2197 tree target = gimple_call_fn (call);
2198 ipa_polymorphic_call_context context (current_function_decl,
2199 target, call, &instance);
2201 gcc_checking_assert (cs->indirect_info->otr_type
2202 == obj_type_ref_class (target));
2203 gcc_checking_assert (cs->indirect_info->otr_token
2204 == tree_to_shwi (OBJ_TYPE_REF_TOKEN (target)));
2206 cs->indirect_info->vptr_changed
2207 = !context.get_dynamic_type (instance,
2208 OBJ_TYPE_REF_OBJECT (target),
2209 obj_type_ref_class (target), call);
2210 cs->indirect_info->context = context;
2213 if (TREE_CODE (target) == SSA_NAME)
2214 ipa_analyze_indirect_call_uses (fbi, call, target);
2215 else if (virtual_method_call_p (target))
2216 ipa_analyze_virtual_call_uses (fbi, call, target);
2220 /* Analyze the call statement STMT with respect to formal parameters (described
2221 in INFO) of caller given by FBI->NODE. Currently it only checks whether
2222 formal parameters are called. */
2224 static void
2225 ipa_analyze_stmt_uses (struct func_body_info *fbi, gimple stmt)
2227 if (is_gimple_call (stmt))
2228 ipa_analyze_call_uses (fbi, as_a <gcall *> (stmt));
2231 /* Callback of walk_stmt_load_store_addr_ops for the visit_load.
2232 If OP is a parameter declaration, mark it as used in the info structure
2233 passed in DATA. */
2235 static bool
2236 visit_ref_for_mod_analysis (gimple, tree op, tree, void *data)
2238 struct ipa_node_params *info = (struct ipa_node_params *) data;
2240 op = get_base_address (op);
2241 if (op
2242 && TREE_CODE (op) == PARM_DECL)
2244 int index = ipa_get_param_decl_index (info, op);
2245 gcc_assert (index >= 0);
2246 ipa_set_param_used (info, index, true);
2249 return false;
2252 /* Scan the statements in BB and inspect the uses of formal parameters. Store
2253 the findings in various structures of the associated ipa_node_params
2254 structure, such as parameter flags, notes etc. FBI holds various data about
2255 the function being analyzed. */
2257 static void
2258 ipa_analyze_params_uses_in_bb (struct func_body_info *fbi, basic_block bb)
2260 gimple_stmt_iterator gsi;
2261 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2263 gimple stmt = gsi_stmt (gsi);
2265 if (is_gimple_debug (stmt))
2266 continue;
2268 ipa_analyze_stmt_uses (fbi, stmt);
2269 walk_stmt_load_store_addr_ops (stmt, fbi->info,
2270 visit_ref_for_mod_analysis,
2271 visit_ref_for_mod_analysis,
2272 visit_ref_for_mod_analysis);
2274 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2275 walk_stmt_load_store_addr_ops (gsi_stmt (gsi), fbi->info,
2276 visit_ref_for_mod_analysis,
2277 visit_ref_for_mod_analysis,
2278 visit_ref_for_mod_analysis);
2281 /* Calculate controlled uses of parameters of NODE. */
2283 static void
2284 ipa_analyze_controlled_uses (struct cgraph_node *node)
2286 struct ipa_node_params *info = IPA_NODE_REF (node);
2288 for (int i = 0; i < ipa_get_param_count (info); i++)
2290 tree parm = ipa_get_param (info, i);
2291 int controlled_uses = 0;
2293 /* For SSA regs see if parameter is used. For non-SSA we compute
2294 the flag during modification analysis. */
2295 if (is_gimple_reg (parm))
2297 tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl),
2298 parm);
2299 if (ddef && !has_zero_uses (ddef))
2301 imm_use_iterator imm_iter;
2302 use_operand_p use_p;
2304 ipa_set_param_used (info, i, true);
2305 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, ddef)
2306 if (!is_gimple_call (USE_STMT (use_p)))
2308 if (!is_gimple_debug (USE_STMT (use_p)))
2310 controlled_uses = IPA_UNDESCRIBED_USE;
2311 break;
2314 else
2315 controlled_uses++;
2317 else
2318 controlled_uses = 0;
2320 else
2321 controlled_uses = IPA_UNDESCRIBED_USE;
2322 ipa_set_controlled_uses (info, i, controlled_uses);
2326 /* Free stuff in BI. */
2328 static void
2329 free_ipa_bb_info (struct ipa_bb_info *bi)
2331 bi->cg_edges.release ();
2332 bi->param_aa_statuses.release ();
2335 /* Dominator walker driving the analysis. */
2337 class analysis_dom_walker : public dom_walker
2339 public:
2340 analysis_dom_walker (struct func_body_info *fbi)
2341 : dom_walker (CDI_DOMINATORS), m_fbi (fbi) {}
2343 virtual void before_dom_children (basic_block);
2345 private:
2346 struct func_body_info *m_fbi;
2349 void
2350 analysis_dom_walker::before_dom_children (basic_block bb)
2352 ipa_analyze_params_uses_in_bb (m_fbi, bb);
2353 ipa_compute_jump_functions_for_bb (m_fbi, bb);
2356 /* Initialize the array describing properties of of formal parameters
2357 of NODE, analyze their uses and compute jump functions associated
2358 with actual arguments of calls from within NODE. */
2360 void
2361 ipa_analyze_node (struct cgraph_node *node)
2363 struct func_body_info fbi;
2364 struct ipa_node_params *info;
2366 ipa_check_create_node_params ();
2367 ipa_check_create_edge_args ();
2368 info = IPA_NODE_REF (node);
2370 if (info->analysis_done)
2371 return;
2372 info->analysis_done = 1;
2374 if (ipa_func_spec_opts_forbid_analysis_p (node))
2376 for (int i = 0; i < ipa_get_param_count (info); i++)
2378 ipa_set_param_used (info, i, true);
2379 ipa_set_controlled_uses (info, i, IPA_UNDESCRIBED_USE);
2381 return;
2384 struct function *func = DECL_STRUCT_FUNCTION (node->decl);
2385 push_cfun (func);
2386 calculate_dominance_info (CDI_DOMINATORS);
2387 ipa_initialize_node_params (node);
2388 ipa_analyze_controlled_uses (node);
2390 fbi.node = node;
2391 fbi.info = IPA_NODE_REF (node);
2392 fbi.bb_infos = vNULL;
2393 fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun));
2394 fbi.param_count = ipa_get_param_count (info);
2395 fbi.aa_walked = 0;
2397 for (struct cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
2399 ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
2400 bi->cg_edges.safe_push (cs);
2403 for (struct cgraph_edge *cs = node->indirect_calls; cs; cs = cs->next_callee)
2405 ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
2406 bi->cg_edges.safe_push (cs);
2409 analysis_dom_walker (&fbi).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
2411 int i;
2412 struct ipa_bb_info *bi;
2413 FOR_EACH_VEC_ELT (fbi.bb_infos, i, bi)
2414 free_ipa_bb_info (bi);
2415 fbi.bb_infos.release ();
2416 free_dominance_info (CDI_DOMINATORS);
2417 pop_cfun ();
2420 /* Update the jump functions associated with call graph edge E when the call
2421 graph edge CS is being inlined, assuming that E->caller is already (possibly
2422 indirectly) inlined into CS->callee and that E has not been inlined. */
2424 static void
2425 update_jump_functions_after_inlining (struct cgraph_edge *cs,
2426 struct cgraph_edge *e)
2428 struct ipa_edge_args *top = IPA_EDGE_REF (cs);
2429 struct ipa_edge_args *args = IPA_EDGE_REF (e);
2430 int count = ipa_get_cs_argument_count (args);
2431 int i;
2433 for (i = 0; i < count; i++)
2435 struct ipa_jump_func *dst = ipa_get_ith_jump_func (args, i);
2436 struct ipa_polymorphic_call_context *dst_ctx
2437 = ipa_get_ith_polymorhic_call_context (args, i);
2439 if (dst->type == IPA_JF_ANCESTOR)
2441 struct ipa_jump_func *src;
2442 int dst_fid = dst->value.ancestor.formal_id;
2443 struct ipa_polymorphic_call_context *src_ctx
2444 = ipa_get_ith_polymorhic_call_context (top, dst_fid);
2446 /* Variable number of arguments can cause havoc if we try to access
2447 one that does not exist in the inlined edge. So make sure we
2448 don't. */
2449 if (dst_fid >= ipa_get_cs_argument_count (top))
2451 ipa_set_jf_unknown (dst);
2452 continue;
2455 src = ipa_get_ith_jump_func (top, dst_fid);
2457 if (src_ctx && !src_ctx->useless_p ())
2459 struct ipa_polymorphic_call_context ctx = *src_ctx;
2461 /* TODO: Make type preserved safe WRT contexts. */
2462 if (!ipa_get_jf_ancestor_type_preserved (dst))
2463 ctx.possible_dynamic_type_change (e->in_polymorphic_cdtor);
2464 ctx.offset_by (dst->value.ancestor.offset);
2465 if (!ctx.useless_p ())
2467 vec_safe_grow_cleared (args->polymorphic_call_contexts,
2468 count);
2469 dst_ctx = ipa_get_ith_polymorhic_call_context (args, i);
2471 dst_ctx->combine_with (ctx);
2474 if (src->agg.items
2475 && (dst->value.ancestor.agg_preserved || !src->agg.by_ref))
2477 struct ipa_agg_jf_item *item;
2478 int j;
2480 /* Currently we do not produce clobber aggregate jump functions,
2481 replace with merging when we do. */
2482 gcc_assert (!dst->agg.items);
2484 dst->agg.items = vec_safe_copy (src->agg.items);
2485 dst->agg.by_ref = src->agg.by_ref;
2486 FOR_EACH_VEC_SAFE_ELT (dst->agg.items, j, item)
2487 item->offset -= dst->value.ancestor.offset;
2490 if (src->type == IPA_JF_PASS_THROUGH
2491 && src->value.pass_through.operation == NOP_EXPR)
2493 dst->value.ancestor.formal_id = src->value.pass_through.formal_id;
2494 dst->value.ancestor.agg_preserved &=
2495 src->value.pass_through.agg_preserved;
2497 else if (src->type == IPA_JF_ANCESTOR)
2499 dst->value.ancestor.formal_id = src->value.ancestor.formal_id;
2500 dst->value.ancestor.offset += src->value.ancestor.offset;
2501 dst->value.ancestor.agg_preserved &=
2502 src->value.ancestor.agg_preserved;
2504 else
2505 ipa_set_jf_unknown (dst);
2507 else if (dst->type == IPA_JF_PASS_THROUGH)
2509 struct ipa_jump_func *src;
2510 /* We must check range due to calls with variable number of arguments
2511 and we cannot combine jump functions with operations. */
2512 if (dst->value.pass_through.operation == NOP_EXPR
2513 && (dst->value.pass_through.formal_id
2514 < ipa_get_cs_argument_count (top)))
2516 int dst_fid = dst->value.pass_through.formal_id;
2517 src = ipa_get_ith_jump_func (top, dst_fid);
2518 bool dst_agg_p = ipa_get_jf_pass_through_agg_preserved (dst);
2519 struct ipa_polymorphic_call_context *src_ctx
2520 = ipa_get_ith_polymorhic_call_context (top, dst_fid);
2522 if (src_ctx && !src_ctx->useless_p ())
2524 struct ipa_polymorphic_call_context ctx = *src_ctx;
2526 /* TODO: Make type preserved safe WRT contexts. */
2527 if (!ipa_get_jf_pass_through_type_preserved (dst))
2528 ctx.possible_dynamic_type_change (e->in_polymorphic_cdtor);
2529 if (!ctx.useless_p ())
2531 if (!dst_ctx)
2533 vec_safe_grow_cleared (args->polymorphic_call_contexts,
2534 count);
2535 dst_ctx = ipa_get_ith_polymorhic_call_context (args, i);
2537 dst_ctx->combine_with (ctx);
2540 switch (src->type)
2542 case IPA_JF_UNKNOWN:
2543 ipa_set_jf_unknown (dst);
2544 break;
2545 case IPA_JF_CONST:
2546 ipa_set_jf_cst_copy (dst, src);
2547 break;
2549 case IPA_JF_PASS_THROUGH:
2551 int formal_id = ipa_get_jf_pass_through_formal_id (src);
2552 enum tree_code operation;
2553 operation = ipa_get_jf_pass_through_operation (src);
2555 if (operation == NOP_EXPR)
2557 bool agg_p;
2558 agg_p = dst_agg_p
2559 && ipa_get_jf_pass_through_agg_preserved (src);
2560 ipa_set_jf_simple_pass_through (dst, formal_id, agg_p);
2562 else
2564 tree operand = ipa_get_jf_pass_through_operand (src);
2565 ipa_set_jf_arith_pass_through (dst, formal_id, operand,
2566 operation);
2568 break;
2570 case IPA_JF_ANCESTOR:
2572 bool agg_p;
2573 agg_p = dst_agg_p
2574 && ipa_get_jf_ancestor_agg_preserved (src);
2575 ipa_set_ancestor_jf (dst,
2576 ipa_get_jf_ancestor_offset (src),
2577 ipa_get_jf_ancestor_formal_id (src),
2578 agg_p);
2579 break;
2581 default:
2582 gcc_unreachable ();
2585 if (src->agg.items
2586 && (dst_agg_p || !src->agg.by_ref))
2588 /* Currently we do not produce clobber aggregate jump
2589 functions, replace with merging when we do. */
2590 gcc_assert (!dst->agg.items);
2592 dst->agg.by_ref = src->agg.by_ref;
2593 dst->agg.items = vec_safe_copy (src->agg.items);
2596 else
2597 ipa_set_jf_unknown (dst);
2602 /* If TARGET is an addr_expr of a function declaration, make it the
2603 (SPECULATIVE)destination of an indirect edge IE and return the edge.
2604 Otherwise, return NULL. */
2606 struct cgraph_edge *
2607 ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
2608 bool speculative)
2610 struct cgraph_node *callee;
2611 struct inline_edge_summary *es = inline_edge_summary (ie);
2612 bool unreachable = false;
2614 if (TREE_CODE (target) == ADDR_EXPR)
2615 target = TREE_OPERAND (target, 0);
2616 if (TREE_CODE (target) != FUNCTION_DECL)
2618 target = canonicalize_constructor_val (target, NULL);
2619 if (!target || TREE_CODE (target) != FUNCTION_DECL)
2621 if (ie->indirect_info->member_ptr)
2622 /* Member pointer call that goes through a VMT lookup. */
2623 return NULL;
2625 if (dump_enabled_p ())
2627 location_t loc = gimple_location_safe (ie->call_stmt);
2628 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
2629 "discovered direct call to non-function in %s/%i, "
2630 "making it __builtin_unreachable\n",
2631 ie->caller->name (), ie->caller->order);
2634 target = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
2635 callee = cgraph_node::get_create (target);
2636 unreachable = true;
2638 else
2639 callee = cgraph_node::get (target);
2641 else
2642 callee = cgraph_node::get (target);
2644 /* Because may-edges are not explicitely represented and vtable may be external,
2645 we may create the first reference to the object in the unit. */
2646 if (!callee || callee->global.inlined_to)
2649 /* We are better to ensure we can refer to it.
2650 In the case of static functions we are out of luck, since we already
2651 removed its body. In the case of public functions we may or may
2652 not introduce the reference. */
2653 if (!canonicalize_constructor_val (target, NULL)
2654 || !TREE_PUBLIC (target))
2656 if (dump_file)
2657 fprintf (dump_file, "ipa-prop: Discovered call to a known target "
2658 "(%s/%i -> %s/%i) but can not refer to it. Giving up.\n",
2659 xstrdup_for_dump (ie->caller->name ()),
2660 ie->caller->order,
2661 xstrdup_for_dump (ie->callee->name ()),
2662 ie->callee->order);
2663 return NULL;
2665 callee = cgraph_node::get_create (target);
2668 /* If the edge is already speculated. */
2669 if (speculative && ie->speculative)
2671 struct cgraph_edge *e2;
2672 struct ipa_ref *ref;
2673 ie->speculative_call_info (e2, ie, ref);
2674 if (e2->callee->ultimate_alias_target ()
2675 != callee->ultimate_alias_target ())
2677 if (dump_file)
2678 fprintf (dump_file, "ipa-prop: Discovered call to a speculative target "
2679 "(%s/%i -> %s/%i) but the call is already speculated to %s/%i. Giving up.\n",
2680 xstrdup_for_dump (ie->caller->name ()),
2681 ie->caller->order,
2682 xstrdup_for_dump (callee->name ()),
2683 callee->order,
2684 xstrdup_for_dump (e2->callee->name ()),
2685 e2->callee->order);
2687 else
2689 if (dump_file)
2690 fprintf (dump_file, "ipa-prop: Discovered call to a speculative target "
2691 "(%s/%i -> %s/%i) this agree with previous speculation.\n",
2692 xstrdup_for_dump (ie->caller->name ()),
2693 ie->caller->order,
2694 xstrdup_for_dump (callee->name ()),
2695 callee->order);
2697 return NULL;
2700 if (!dbg_cnt (devirt))
2701 return NULL;
2703 ipa_check_create_node_params ();
2705 /* We can not make edges to inline clones. It is bug that someone removed
2706 the cgraph node too early. */
2707 gcc_assert (!callee->global.inlined_to);
2709 if (dump_file && !unreachable)
2711 fprintf (dump_file, "ipa-prop: Discovered %s call to a %s target "
2712 "(%s/%i -> %s/%i), for stmt ",
2713 ie->indirect_info->polymorphic ? "a virtual" : "an indirect",
2714 speculative ? "speculative" : "known",
2715 xstrdup_for_dump (ie->caller->name ()),
2716 ie->caller->order,
2717 xstrdup_for_dump (callee->name ()),
2718 callee->order);
2719 if (ie->call_stmt)
2720 print_gimple_stmt (dump_file, ie->call_stmt, 2, TDF_SLIM);
2721 else
2722 fprintf (dump_file, "with uid %i\n", ie->lto_stmt_uid);
2724 if (dump_enabled_p ())
2726 location_t loc = gimple_location_safe (ie->call_stmt);
2728 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
2729 "converting indirect call in %s to direct call to %s\n",
2730 ie->caller->name (), callee->name ());
2732 if (!speculative)
2733 ie = ie->make_direct (callee);
2734 else
2736 if (!callee->can_be_discarded_p ())
2738 cgraph_node *alias;
2739 alias = dyn_cast<cgraph_node *> (callee->noninterposable_alias ());
2740 if (alias)
2741 callee = alias;
2743 ie = ie->make_speculative
2744 (callee, ie->count * 8 / 10, ie->frequency * 8 / 10);
2746 es = inline_edge_summary (ie);
2747 es->call_stmt_size -= (eni_size_weights.indirect_call_cost
2748 - eni_size_weights.call_cost);
2749 es->call_stmt_time -= (eni_time_weights.indirect_call_cost
2750 - eni_time_weights.call_cost);
2752 return ie;
2755 /* Retrieve value from aggregate jump function AGG for the given OFFSET or
2756 return NULL if there is not any. BY_REF specifies whether the value has to
2757 be passed by reference or by value. */
2759 tree
2760 ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *agg,
2761 HOST_WIDE_INT offset, bool by_ref)
2763 struct ipa_agg_jf_item *item;
2764 int i;
2766 if (by_ref != agg->by_ref)
2767 return NULL;
2769 FOR_EACH_VEC_SAFE_ELT (agg->items, i, item)
2770 if (item->offset == offset)
2772 /* Currently we do not have clobber values, return NULL for them once
2773 we do. */
2774 gcc_checking_assert (is_gimple_ip_invariant (item->value));
2775 return item->value;
2777 return NULL;
2780 /* Remove a reference to SYMBOL from the list of references of a node given by
2781 reference description RDESC. Return true if the reference has been
2782 successfully found and removed. */
2784 static bool
2785 remove_described_reference (symtab_node *symbol, struct ipa_cst_ref_desc *rdesc)
2787 struct ipa_ref *to_del;
2788 struct cgraph_edge *origin;
2790 origin = rdesc->cs;
2791 if (!origin)
2792 return false;
2793 to_del = origin->caller->find_reference (symbol, origin->call_stmt,
2794 origin->lto_stmt_uid);
2795 if (!to_del)
2796 return false;
2798 to_del->remove_reference ();
2799 if (dump_file)
2800 fprintf (dump_file, "ipa-prop: Removed a reference from %s/%i to %s.\n",
2801 xstrdup_for_dump (origin->caller->name ()),
2802 origin->caller->order, xstrdup_for_dump (symbol->name ()));
2803 return true;
2806 /* If JFUNC has a reference description with refcount different from
2807 IPA_UNDESCRIBED_USE, return the reference description, otherwise return
2808 NULL. JFUNC must be a constant jump function. */
2810 static struct ipa_cst_ref_desc *
2811 jfunc_rdesc_usable (struct ipa_jump_func *jfunc)
2813 struct ipa_cst_ref_desc *rdesc = ipa_get_jf_constant_rdesc (jfunc);
2814 if (rdesc && rdesc->refcount != IPA_UNDESCRIBED_USE)
2815 return rdesc;
2816 else
2817 return NULL;
2820 /* If the value of constant jump function JFUNC is an address of a function
2821 declaration, return the associated call graph node. Otherwise return
2822 NULL. */
2824 static cgraph_node *
2825 cgraph_node_for_jfunc (struct ipa_jump_func *jfunc)
2827 gcc_checking_assert (jfunc->type == IPA_JF_CONST);
2828 tree cst = ipa_get_jf_constant (jfunc);
2829 if (TREE_CODE (cst) != ADDR_EXPR
2830 || TREE_CODE (TREE_OPERAND (cst, 0)) != FUNCTION_DECL)
2831 return NULL;
2833 return cgraph_node::get (TREE_OPERAND (cst, 0));
2837 /* If JFUNC is a constant jump function with a usable rdesc, decrement its
2838 refcount and if it hits zero, remove reference to SYMBOL from the caller of
2839 the edge specified in the rdesc. Return false if either the symbol or the
2840 reference could not be found, otherwise return true. */
2842 static bool
2843 try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc)
2845 struct ipa_cst_ref_desc *rdesc;
2846 if (jfunc->type == IPA_JF_CONST
2847 && (rdesc = jfunc_rdesc_usable (jfunc))
2848 && --rdesc->refcount == 0)
2850 symtab_node *symbol = cgraph_node_for_jfunc (jfunc);
2851 if (!symbol)
2852 return false;
2854 return remove_described_reference (symbol, rdesc);
2856 return true;
2859 /* Try to find a destination for indirect edge IE that corresponds to a simple
2860 call or a call of a member function pointer and where the destination is a
2861 pointer formal parameter described by jump function JFUNC. If it can be
2862 determined, return the newly direct edge, otherwise return NULL.
2863 NEW_ROOT_INFO is the node info that JFUNC lattices are relative to. */
2865 static struct cgraph_edge *
2866 try_make_edge_direct_simple_call (struct cgraph_edge *ie,
2867 struct ipa_jump_func *jfunc,
2868 struct ipa_node_params *new_root_info)
2870 struct cgraph_edge *cs;
2871 tree target;
2872 bool agg_contents = ie->indirect_info->agg_contents;
2874 if (ie->indirect_info->agg_contents)
2875 target = ipa_find_agg_cst_for_param (&jfunc->agg,
2876 ie->indirect_info->offset,
2877 ie->indirect_info->by_ref);
2878 else
2879 target = ipa_value_from_jfunc (new_root_info, jfunc);
2880 if (!target)
2881 return NULL;
2882 cs = ipa_make_edge_direct_to_target (ie, target);
2884 if (cs && !agg_contents)
2886 bool ok;
2887 gcc_checking_assert (cs->callee
2888 && (cs != ie
2889 || jfunc->type != IPA_JF_CONST
2890 || !cgraph_node_for_jfunc (jfunc)
2891 || cs->callee == cgraph_node_for_jfunc (jfunc)));
2892 ok = try_decrement_rdesc_refcount (jfunc);
2893 gcc_checking_assert (ok);
2896 return cs;
2899 /* Return the target to be used in cases of impossible devirtualization. IE
2900 and target (the latter can be NULL) are dumped when dumping is enabled. */
2902 tree
2903 ipa_impossible_devirt_target (struct cgraph_edge *ie, tree target)
2905 if (dump_file)
2907 if (target)
2908 fprintf (dump_file,
2909 "Type inconsistent devirtualization: %s/%i->%s\n",
2910 ie->caller->name (), ie->caller->order,
2911 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (target)));
2912 else
2913 fprintf (dump_file,
2914 "No devirtualization target in %s/%i\n",
2915 ie->caller->name (), ie->caller->order);
2917 tree new_target = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
2918 cgraph_node::get_create (new_target);
2919 return new_target;
2922 /* Try to find a destination for indirect edge IE that corresponds to a virtual
2923 call based on a formal parameter which is described by jump function JFUNC
2924 and if it can be determined, make it direct and return the direct edge.
2925 Otherwise, return NULL. CTX describes the polymorphic context that the
2926 parameter the call is based on brings along with it. */
2928 static struct cgraph_edge *
2929 try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
2930 struct ipa_jump_func *jfunc,
2931 struct ipa_polymorphic_call_context ctx)
2933 tree target = NULL;
2934 bool speculative = false;
2936 if (!opt_for_fn (ie->caller->decl, flag_devirtualize))
2937 return NULL;
2939 gcc_assert (!ie->indirect_info->by_ref);
2941 /* Try to do lookup via known virtual table pointer value. */
2942 if (!ie->indirect_info->vptr_changed
2943 || opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively))
2945 tree vtable;
2946 unsigned HOST_WIDE_INT offset;
2947 tree t = ipa_find_agg_cst_for_param (&jfunc->agg,
2948 ie->indirect_info->offset,
2949 true);
2950 if (t && vtable_pointer_value_to_vtable (t, &vtable, &offset))
2952 t = gimple_get_virt_method_for_vtable (ie->indirect_info->otr_token,
2953 vtable, offset);
2954 if (t)
2956 if ((TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE
2957 && DECL_FUNCTION_CODE (t) == BUILT_IN_UNREACHABLE)
2958 || !possible_polymorphic_call_target_p
2959 (ie, cgraph_node::get (t)))
2961 /* Do not speculate builtin_unreachable, it is stpid! */
2962 if (!ie->indirect_info->vptr_changed)
2963 target = ipa_impossible_devirt_target (ie, target);
2965 else
2967 target = t;
2968 speculative = ie->indirect_info->vptr_changed;
2974 ipa_polymorphic_call_context ie_context (ie);
2975 vec <cgraph_node *>targets;
2976 bool final;
2978 ctx.offset_by (ie->indirect_info->offset);
2979 if (ie->indirect_info->vptr_changed)
2980 ctx.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
2981 ie->indirect_info->otr_type);
2982 ctx.combine_with (ie_context, ie->indirect_info->otr_type);
2983 targets = possible_polymorphic_call_targets
2984 (ie->indirect_info->otr_type,
2985 ie->indirect_info->otr_token,
2986 ctx, &final);
2987 if (final && targets.length () <= 1)
2989 if (targets.length () == 1)
2990 target = targets[0]->decl;
2991 else
2992 target = ipa_impossible_devirt_target (ie, NULL_TREE);
2994 else if (!target && opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively)
2995 && !ie->speculative && ie->maybe_hot_p ())
2997 cgraph_node *n;
2998 n = try_speculative_devirtualization (ie->indirect_info->otr_type,
2999 ie->indirect_info->otr_token,
3000 ie->indirect_info->context);
3001 if (n)
3003 target = n->decl;
3004 speculative = true;
3008 if (target)
3010 if (!possible_polymorphic_call_target_p
3011 (ie, cgraph_node::get_create (target)))
3013 if (speculative)
3014 return NULL;
3015 target = ipa_impossible_devirt_target (ie, target);
3017 return ipa_make_edge_direct_to_target (ie, target, speculative);
3019 else
3020 return NULL;
3023 /* Update the param called notes associated with NODE when CS is being inlined,
3024 assuming NODE is (potentially indirectly) inlined into CS->callee.
3025 Moreover, if the callee is discovered to be constant, create a new cgraph
3026 edge for it. Newly discovered indirect edges will be added to *NEW_EDGES,
3027 unless NEW_EDGES is NULL. Return true iff a new edge(s) were created. */
3029 static bool
3030 update_indirect_edges_after_inlining (struct cgraph_edge *cs,
3031 struct cgraph_node *node,
3032 vec<cgraph_edge *> *new_edges)
3034 struct ipa_edge_args *top;
3035 struct cgraph_edge *ie, *next_ie, *new_direct_edge;
3036 struct ipa_node_params *new_root_info;
3037 bool res = false;
3039 ipa_check_create_edge_args ();
3040 top = IPA_EDGE_REF (cs);
3041 new_root_info = IPA_NODE_REF (cs->caller->global.inlined_to
3042 ? cs->caller->global.inlined_to
3043 : cs->caller);
3045 for (ie = node->indirect_calls; ie; ie = next_ie)
3047 struct cgraph_indirect_call_info *ici = ie->indirect_info;
3048 struct ipa_jump_func *jfunc;
3049 int param_index;
3051 next_ie = ie->next_callee;
3053 if (ici->param_index == -1)
3054 continue;
3056 /* We must check range due to calls with variable number of arguments: */
3057 if (ici->param_index >= ipa_get_cs_argument_count (top))
3059 ici->param_index = -1;
3060 continue;
3063 param_index = ici->param_index;
3064 jfunc = ipa_get_ith_jump_func (top, param_index);
3066 if (!opt_for_fn (node->decl, flag_indirect_inlining))
3067 new_direct_edge = NULL;
3068 else if (ici->polymorphic)
3070 ipa_polymorphic_call_context ctx;
3071 ctx = ipa_context_from_jfunc (new_root_info, cs, param_index, jfunc);
3072 new_direct_edge = try_make_edge_direct_virtual_call (ie, jfunc, ctx);
3074 else
3075 new_direct_edge = try_make_edge_direct_simple_call (ie, jfunc,
3076 new_root_info);
3077 /* If speculation was removed, then we need to do nothing. */
3078 if (new_direct_edge && new_direct_edge != ie)
3080 new_direct_edge->indirect_inlining_edge = 1;
3081 top = IPA_EDGE_REF (cs);
3082 res = true;
3084 else if (new_direct_edge)
3086 new_direct_edge->indirect_inlining_edge = 1;
3087 if (new_direct_edge->call_stmt)
3088 new_direct_edge->call_stmt_cannot_inline_p
3089 = !gimple_check_call_matching_types (
3090 new_direct_edge->call_stmt,
3091 new_direct_edge->callee->decl, false);
3092 if (new_edges)
3094 new_edges->safe_push (new_direct_edge);
3095 res = true;
3097 top = IPA_EDGE_REF (cs);
3099 else if (jfunc->type == IPA_JF_PASS_THROUGH
3100 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
3102 if ((ici->agg_contents
3103 && !ipa_get_jf_pass_through_agg_preserved (jfunc))
3104 || (ici->polymorphic
3105 && !ipa_get_jf_pass_through_type_preserved (jfunc)))
3106 ici->param_index = -1;
3107 else
3108 ici->param_index = ipa_get_jf_pass_through_formal_id (jfunc);
3110 else if (jfunc->type == IPA_JF_ANCESTOR)
3112 if ((ici->agg_contents
3113 && !ipa_get_jf_ancestor_agg_preserved (jfunc))
3114 || (ici->polymorphic
3115 && !ipa_get_jf_ancestor_type_preserved (jfunc)))
3116 ici->param_index = -1;
3117 else
3119 ici->param_index = ipa_get_jf_ancestor_formal_id (jfunc);
3120 ici->offset += ipa_get_jf_ancestor_offset (jfunc);
3123 else
3124 /* Either we can find a destination for this edge now or never. */
3125 ici->param_index = -1;
3128 return res;
3131 /* Recursively traverse subtree of NODE (including node) made of inlined
3132 cgraph_edges when CS has been inlined and invoke
3133 update_indirect_edges_after_inlining on all nodes and
3134 update_jump_functions_after_inlining on all non-inlined edges that lead out
3135 of this subtree. Newly discovered indirect edges will be added to
3136 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were
3137 created. */
3139 static bool
3140 propagate_info_to_inlined_callees (struct cgraph_edge *cs,
3141 struct cgraph_node *node,
3142 vec<cgraph_edge *> *new_edges)
3144 struct cgraph_edge *e;
3145 bool res;
3147 res = update_indirect_edges_after_inlining (cs, node, new_edges);
3149 for (e = node->callees; e; e = e->next_callee)
3150 if (!e->inline_failed)
3151 res |= propagate_info_to_inlined_callees (cs, e->callee, new_edges);
3152 else
3153 update_jump_functions_after_inlining (cs, e);
3154 for (e = node->indirect_calls; e; e = e->next_callee)
3155 update_jump_functions_after_inlining (cs, e);
3157 return res;
3160 /* Combine two controlled uses counts as done during inlining. */
3162 static int
3163 combine_controlled_uses_counters (int c, int d)
3165 if (c == IPA_UNDESCRIBED_USE || d == IPA_UNDESCRIBED_USE)
3166 return IPA_UNDESCRIBED_USE;
3167 else
3168 return c + d - 1;
3171 /* Propagate number of controlled users from CS->caleee to the new root of the
3172 tree of inlined nodes. */
3174 static void
3175 propagate_controlled_uses (struct cgraph_edge *cs)
3177 struct ipa_edge_args *args = IPA_EDGE_REF (cs);
3178 struct cgraph_node *new_root = cs->caller->global.inlined_to
3179 ? cs->caller->global.inlined_to : cs->caller;
3180 struct ipa_node_params *new_root_info = IPA_NODE_REF (new_root);
3181 struct ipa_node_params *old_root_info = IPA_NODE_REF (cs->callee);
3182 int count, i;
3184 count = MIN (ipa_get_cs_argument_count (args),
3185 ipa_get_param_count (old_root_info));
3186 for (i = 0; i < count; i++)
3188 struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
3189 struct ipa_cst_ref_desc *rdesc;
3191 if (jf->type == IPA_JF_PASS_THROUGH)
3193 int src_idx, c, d;
3194 src_idx = ipa_get_jf_pass_through_formal_id (jf);
3195 c = ipa_get_controlled_uses (new_root_info, src_idx);
3196 d = ipa_get_controlled_uses (old_root_info, i);
3198 gcc_checking_assert (ipa_get_jf_pass_through_operation (jf)
3199 == NOP_EXPR || c == IPA_UNDESCRIBED_USE);
3200 c = combine_controlled_uses_counters (c, d);
3201 ipa_set_controlled_uses (new_root_info, src_idx, c);
3202 if (c == 0 && new_root_info->ipcp_orig_node)
3204 struct cgraph_node *n;
3205 struct ipa_ref *ref;
3206 tree t = new_root_info->known_csts[src_idx];
3208 if (t && TREE_CODE (t) == ADDR_EXPR
3209 && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
3210 && (n = cgraph_node::get (TREE_OPERAND (t, 0)))
3211 && (ref = new_root->find_reference (n, NULL, 0)))
3213 if (dump_file)
3214 fprintf (dump_file, "ipa-prop: Removing cloning-created "
3215 "reference from %s/%i to %s/%i.\n",
3216 xstrdup_for_dump (new_root->name ()),
3217 new_root->order,
3218 xstrdup_for_dump (n->name ()), n->order);
3219 ref->remove_reference ();
3223 else if (jf->type == IPA_JF_CONST
3224 && (rdesc = jfunc_rdesc_usable (jf)))
3226 int d = ipa_get_controlled_uses (old_root_info, i);
3227 int c = rdesc->refcount;
3228 rdesc->refcount = combine_controlled_uses_counters (c, d);
3229 if (rdesc->refcount == 0)
3231 tree cst = ipa_get_jf_constant (jf);
3232 struct cgraph_node *n;
3233 gcc_checking_assert (TREE_CODE (cst) == ADDR_EXPR
3234 && TREE_CODE (TREE_OPERAND (cst, 0))
3235 == FUNCTION_DECL);
3236 n = cgraph_node::get (TREE_OPERAND (cst, 0));
3237 if (n)
3239 struct cgraph_node *clone;
3240 bool ok;
3241 ok = remove_described_reference (n, rdesc);
3242 gcc_checking_assert (ok);
3244 clone = cs->caller;
3245 while (clone->global.inlined_to
3246 && clone != rdesc->cs->caller
3247 && IPA_NODE_REF (clone)->ipcp_orig_node)
3249 struct ipa_ref *ref;
3250 ref = clone->find_reference (n, NULL, 0);
3251 if (ref)
3253 if (dump_file)
3254 fprintf (dump_file, "ipa-prop: Removing "
3255 "cloning-created reference "
3256 "from %s/%i to %s/%i.\n",
3257 xstrdup_for_dump (clone->name ()),
3258 clone->order,
3259 xstrdup_for_dump (n->name ()),
3260 n->order);
3261 ref->remove_reference ();
3263 clone = clone->callers->caller;
3270 for (i = ipa_get_param_count (old_root_info);
3271 i < ipa_get_cs_argument_count (args);
3272 i++)
3274 struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
3276 if (jf->type == IPA_JF_CONST)
3278 struct ipa_cst_ref_desc *rdesc = jfunc_rdesc_usable (jf);
3279 if (rdesc)
3280 rdesc->refcount = IPA_UNDESCRIBED_USE;
3282 else if (jf->type == IPA_JF_PASS_THROUGH)
3283 ipa_set_controlled_uses (new_root_info,
3284 jf->value.pass_through.formal_id,
3285 IPA_UNDESCRIBED_USE);
3289 /* Update jump functions and call note functions on inlining the call site CS.
3290 CS is expected to lead to a node already cloned by
3291 cgraph_clone_inline_nodes. Newly discovered indirect edges will be added to
3292 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were +
3293 created. */
3295 bool
3296 ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
3297 vec<cgraph_edge *> *new_edges)
3299 bool changed;
3300 /* Do nothing if the preparation phase has not been carried out yet
3301 (i.e. during early inlining). */
3302 if (!ipa_node_params_sum)
3303 return false;
3304 gcc_assert (ipa_edge_args_vector);
3306 propagate_controlled_uses (cs);
3307 changed = propagate_info_to_inlined_callees (cs, cs->callee, new_edges);
3309 return changed;
3312 /* Frees all dynamically allocated structures that the argument info points
3313 to. */
3315 void
3316 ipa_free_edge_args_substructures (struct ipa_edge_args *args)
3318 vec_free (args->jump_functions);
3319 memset (args, 0, sizeof (*args));
3322 /* Free all ipa_edge structures. */
3324 void
3325 ipa_free_all_edge_args (void)
3327 int i;
3328 struct ipa_edge_args *args;
3330 if (!ipa_edge_args_vector)
3331 return;
3333 FOR_EACH_VEC_ELT (*ipa_edge_args_vector, i, args)
3334 ipa_free_edge_args_substructures (args);
3336 vec_free (ipa_edge_args_vector);
3339 /* Frees all dynamically allocated structures that the param info points
3340 to. */
3342 ipa_node_params::~ipa_node_params ()
3344 descriptors.release ();
3345 free (lattices);
3346 /* Lattice values and their sources are deallocated with their alocation
3347 pool. */
3348 known_contexts.release ();
3350 lattices = NULL;
3351 ipcp_orig_node = NULL;
3352 analysis_done = 0;
3353 node_enqueued = 0;
3354 do_clone_for_all_contexts = 0;
3355 is_all_contexts_clone = 0;
3356 node_dead = 0;
3359 /* Free all ipa_node_params structures. */
3361 void
3362 ipa_free_all_node_params (void)
3364 delete ipa_node_params_sum;
3365 ipa_node_params_sum = NULL;
3368 /* Grow ipcp_transformations if necessary. */
3370 void
3371 ipcp_grow_transformations_if_necessary (void)
3373 if (vec_safe_length (ipcp_transformations)
3374 <= (unsigned) symtab->cgraph_max_uid)
3375 vec_safe_grow_cleared (ipcp_transformations, symtab->cgraph_max_uid + 1);
3378 /* Set the aggregate replacements of NODE to be AGGVALS. */
3380 void
3381 ipa_set_node_agg_value_chain (struct cgraph_node *node,
3382 struct ipa_agg_replacement_value *aggvals)
3384 ipcp_grow_transformations_if_necessary ();
3385 (*ipcp_transformations)[node->uid].agg_values = aggvals;
3388 /* Hook that is called by cgraph.c when an edge is removed. */
3390 static void
3391 ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
3393 struct ipa_edge_args *args;
3395 /* During IPA-CP updating we can be called on not-yet analyzed clones. */
3396 if (vec_safe_length (ipa_edge_args_vector) <= (unsigned)cs->uid)
3397 return;
3399 args = IPA_EDGE_REF (cs);
3400 if (args->jump_functions)
3402 struct ipa_jump_func *jf;
3403 int i;
3404 FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
3406 struct ipa_cst_ref_desc *rdesc;
3407 try_decrement_rdesc_refcount (jf);
3408 if (jf->type == IPA_JF_CONST
3409 && (rdesc = ipa_get_jf_constant_rdesc (jf))
3410 && rdesc->cs == cs)
3411 rdesc->cs = NULL;
3415 ipa_free_edge_args_substructures (IPA_EDGE_REF (cs));
3418 /* Hook that is called by cgraph.c when an edge is duplicated. */
3420 static void
3421 ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
3422 void *)
3424 struct ipa_edge_args *old_args, *new_args;
3425 unsigned int i;
3427 ipa_check_create_edge_args ();
3429 old_args = IPA_EDGE_REF (src);
3430 new_args = IPA_EDGE_REF (dst);
3432 new_args->jump_functions = vec_safe_copy (old_args->jump_functions);
3433 if (old_args->polymorphic_call_contexts)
3434 new_args->polymorphic_call_contexts
3435 = vec_safe_copy (old_args->polymorphic_call_contexts);
3437 for (i = 0; i < vec_safe_length (old_args->jump_functions); i++)
3439 struct ipa_jump_func *src_jf = ipa_get_ith_jump_func (old_args, i);
3440 struct ipa_jump_func *dst_jf = ipa_get_ith_jump_func (new_args, i);
3442 dst_jf->agg.items = vec_safe_copy (dst_jf->agg.items);
3444 if (src_jf->type == IPA_JF_CONST)
3446 struct ipa_cst_ref_desc *src_rdesc = jfunc_rdesc_usable (src_jf);
3448 if (!src_rdesc)
3449 dst_jf->value.constant.rdesc = NULL;
3450 else if (src->caller == dst->caller)
3452 struct ipa_ref *ref;
3453 symtab_node *n = cgraph_node_for_jfunc (src_jf);
3454 gcc_checking_assert (n);
3455 ref = src->caller->find_reference (n, src->call_stmt,
3456 src->lto_stmt_uid);
3457 gcc_checking_assert (ref);
3458 dst->caller->clone_reference (ref, ref->stmt);
3460 gcc_checking_assert (ipa_refdesc_pool);
3461 struct ipa_cst_ref_desc *dst_rdesc
3462 = (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
3463 dst_rdesc->cs = dst;
3464 dst_rdesc->refcount = src_rdesc->refcount;
3465 dst_rdesc->next_duplicate = NULL;
3466 dst_jf->value.constant.rdesc = dst_rdesc;
3468 else if (src_rdesc->cs == src)
3470 struct ipa_cst_ref_desc *dst_rdesc;
3471 gcc_checking_assert (ipa_refdesc_pool);
3472 dst_rdesc
3473 = (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
3474 dst_rdesc->cs = dst;
3475 dst_rdesc->refcount = src_rdesc->refcount;
3476 dst_rdesc->next_duplicate = src_rdesc->next_duplicate;
3477 src_rdesc->next_duplicate = dst_rdesc;
3478 dst_jf->value.constant.rdesc = dst_rdesc;
3480 else
3482 struct ipa_cst_ref_desc *dst_rdesc;
3483 /* This can happen during inlining, when a JFUNC can refer to a
3484 reference taken in a function up in the tree of inline clones.
3485 We need to find the duplicate that refers to our tree of
3486 inline clones. */
3488 gcc_assert (dst->caller->global.inlined_to);
3489 for (dst_rdesc = src_rdesc->next_duplicate;
3490 dst_rdesc;
3491 dst_rdesc = dst_rdesc->next_duplicate)
3493 struct cgraph_node *top;
3494 top = dst_rdesc->cs->caller->global.inlined_to
3495 ? dst_rdesc->cs->caller->global.inlined_to
3496 : dst_rdesc->cs->caller;
3497 if (dst->caller->global.inlined_to == top)
3498 break;
3500 gcc_assert (dst_rdesc);
3501 dst_jf->value.constant.rdesc = dst_rdesc;
3504 else if (dst_jf->type == IPA_JF_PASS_THROUGH
3505 && src->caller == dst->caller)
3507 struct cgraph_node *inline_root = dst->caller->global.inlined_to
3508 ? dst->caller->global.inlined_to : dst->caller;
3509 struct ipa_node_params *root_info = IPA_NODE_REF (inline_root);
3510 int idx = ipa_get_jf_pass_through_formal_id (dst_jf);
3512 int c = ipa_get_controlled_uses (root_info, idx);
3513 if (c != IPA_UNDESCRIBED_USE)
3515 c++;
3516 ipa_set_controlled_uses (root_info, idx, c);
3522 /* Analyze newly added function into callgraph. */
3524 static void
3525 ipa_add_new_function (cgraph_node *node, void *data ATTRIBUTE_UNUSED)
3527 if (node->has_gimple_body_p ())
3528 ipa_analyze_node (node);
3531 /* Hook that is called by summary when a node is duplicated. */
3533 void
3534 ipa_node_params_t::duplicate(cgraph_node *src, cgraph_node *dst,
3535 ipa_node_params *old_info,
3536 ipa_node_params *new_info)
3538 ipa_agg_replacement_value *old_av, *new_av;
3540 new_info->descriptors = old_info->descriptors.copy ();
3541 new_info->lattices = NULL;
3542 new_info->ipcp_orig_node = old_info->ipcp_orig_node;
3544 new_info->analysis_done = old_info->analysis_done;
3545 new_info->node_enqueued = old_info->node_enqueued;
3547 old_av = ipa_get_agg_replacements_for_node (src);
3548 if (old_av)
3550 new_av = NULL;
3551 while (old_av)
3553 struct ipa_agg_replacement_value *v;
3555 v = ggc_alloc<ipa_agg_replacement_value> ();
3556 memcpy (v, old_av, sizeof (*v));
3557 v->next = new_av;
3558 new_av = v;
3559 old_av = old_av->next;
3561 ipa_set_node_agg_value_chain (dst, new_av);
3564 ipcp_transformation_summary *src_trans = ipcp_get_transformation_summary (src);
3566 if (src_trans && vec_safe_length (src_trans->alignments) > 0)
3568 ipcp_grow_transformations_if_necessary ();
3569 src_trans = ipcp_get_transformation_summary (src);
3570 const vec<ipa_alignment, va_gc> *src_alignments = src_trans->alignments;
3571 vec<ipa_alignment, va_gc> *&dst_alignments
3572 = ipcp_get_transformation_summary (dst)->alignments;
3573 vec_safe_reserve_exact (dst_alignments, src_alignments->length ());
3574 for (unsigned i = 0; i < src_alignments->length (); ++i)
3575 dst_alignments->quick_push ((*src_alignments)[i]);
3579 /* Register our cgraph hooks if they are not already there. */
3581 void
3582 ipa_register_cgraph_hooks (void)
3584 ipa_check_create_node_params ();
3586 if (!edge_removal_hook_holder)
3587 edge_removal_hook_holder =
3588 symtab->add_edge_removal_hook (&ipa_edge_removal_hook, NULL);
3589 if (!edge_duplication_hook_holder)
3590 edge_duplication_hook_holder =
3591 symtab->add_edge_duplication_hook (&ipa_edge_duplication_hook, NULL);
3592 function_insertion_hook_holder =
3593 symtab->add_cgraph_insertion_hook (&ipa_add_new_function, NULL);
3596 /* Unregister our cgraph hooks if they are not already there. */
3598 static void
3599 ipa_unregister_cgraph_hooks (void)
3601 symtab->remove_edge_removal_hook (edge_removal_hook_holder);
3602 edge_removal_hook_holder = NULL;
3603 symtab->remove_edge_duplication_hook (edge_duplication_hook_holder);
3604 edge_duplication_hook_holder = NULL;
3605 symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
3606 function_insertion_hook_holder = NULL;
3609 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
3610 longer needed after ipa-cp. */
3612 void
3613 ipa_free_all_structures_after_ipa_cp (void)
3615 if (!optimize && !in_lto_p)
3617 ipa_free_all_edge_args ();
3618 ipa_free_all_node_params ();
3619 free_alloc_pool (ipcp_sources_pool);
3620 free_alloc_pool (ipcp_cst_values_pool);
3621 free_alloc_pool (ipcp_poly_ctx_values_pool);
3622 free_alloc_pool (ipcp_agg_lattice_pool);
3623 ipa_unregister_cgraph_hooks ();
3624 if (ipa_refdesc_pool)
3625 free_alloc_pool (ipa_refdesc_pool);
3629 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
3630 longer needed after indirect inlining. */
3632 void
3633 ipa_free_all_structures_after_iinln (void)
3635 ipa_free_all_edge_args ();
3636 ipa_free_all_node_params ();
3637 ipa_unregister_cgraph_hooks ();
3638 if (ipcp_sources_pool)
3639 free_alloc_pool (ipcp_sources_pool);
3640 if (ipcp_cst_values_pool)
3641 free_alloc_pool (ipcp_cst_values_pool);
3642 if (ipcp_poly_ctx_values_pool)
3643 free_alloc_pool (ipcp_poly_ctx_values_pool);
3644 if (ipcp_agg_lattice_pool)
3645 free_alloc_pool (ipcp_agg_lattice_pool);
3646 if (ipa_refdesc_pool)
3647 free_alloc_pool (ipa_refdesc_pool);
3650 /* Print ipa_tree_map data structures of all functions in the
3651 callgraph to F. */
3653 void
3654 ipa_print_node_params (FILE *f, struct cgraph_node *node)
3656 int i, count;
3657 struct ipa_node_params *info;
3659 if (!node->definition)
3660 return;
3661 info = IPA_NODE_REF (node);
3662 fprintf (f, " function %s/%i parameter descriptors:\n",
3663 node->name (), node->order);
3664 count = ipa_get_param_count (info);
3665 for (i = 0; i < count; i++)
3667 int c;
3669 fprintf (f, " ");
3670 ipa_dump_param (f, info, i);
3671 if (ipa_is_param_used (info, i))
3672 fprintf (f, " used");
3673 c = ipa_get_controlled_uses (info, i);
3674 if (c == IPA_UNDESCRIBED_USE)
3675 fprintf (f, " undescribed_use");
3676 else
3677 fprintf (f, " controlled_uses=%i", c);
3678 fprintf (f, "\n");
3682 /* Print ipa_tree_map data structures of all functions in the
3683 callgraph to F. */
3685 void
3686 ipa_print_all_params (FILE * f)
3688 struct cgraph_node *node;
3690 fprintf (f, "\nFunction parameters:\n");
3691 FOR_EACH_FUNCTION (node)
3692 ipa_print_node_params (f, node);
3695 /* Return a heap allocated vector containing formal parameters of FNDECL. */
3697 vec<tree>
3698 ipa_get_vector_of_formal_parms (tree fndecl)
3700 vec<tree> args;
3701 int count;
3702 tree parm;
3704 gcc_assert (!flag_wpa);
3705 count = count_formal_params (fndecl);
3706 args.create (count);
3707 for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
3708 args.quick_push (parm);
3710 return args;
3713 /* Return a heap allocated vector containing types of formal parameters of
3714 function type FNTYPE. */
3716 vec<tree>
3717 ipa_get_vector_of_formal_parm_types (tree fntype)
3719 vec<tree> types;
3720 int count = 0;
3721 tree t;
3723 for (t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t))
3724 count++;
3726 types.create (count);
3727 for (t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t))
3728 types.quick_push (TREE_VALUE (t));
3730 return types;
3733 /* Modify the function declaration FNDECL and its type according to the plan in
3734 ADJUSTMENTS. It also sets base fields of individual adjustments structures
3735 to reflect the actual parameters being modified which are determined by the
3736 base_index field. */
3738 void
3739 ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments)
3741 vec<tree> oparms = ipa_get_vector_of_formal_parms (fndecl);
3742 tree orig_type = TREE_TYPE (fndecl);
3743 tree old_arg_types = TYPE_ARG_TYPES (orig_type);
3745 /* The following test is an ugly hack, some functions simply don't have any
3746 arguments in their type. This is probably a bug but well... */
3747 bool care_for_types = (old_arg_types != NULL_TREE);
3748 bool last_parm_void;
3749 vec<tree> otypes;
3750 if (care_for_types)
3752 last_parm_void = (TREE_VALUE (tree_last (old_arg_types))
3753 == void_type_node);
3754 otypes = ipa_get_vector_of_formal_parm_types (orig_type);
3755 if (last_parm_void)
3756 gcc_assert (oparms.length () + 1 == otypes.length ());
3757 else
3758 gcc_assert (oparms.length () == otypes.length ());
3760 else
3762 last_parm_void = false;
3763 otypes.create (0);
3766 int len = adjustments.length ();
3767 tree *link = &DECL_ARGUMENTS (fndecl);
3768 tree new_arg_types = NULL;
3769 for (int i = 0; i < len; i++)
3771 struct ipa_parm_adjustment *adj;
3772 gcc_assert (link);
3774 adj = &adjustments[i];
3775 tree parm;
3776 if (adj->op == IPA_PARM_OP_NEW)
3777 parm = NULL;
3778 else
3779 parm = oparms[adj->base_index];
3780 adj->base = parm;
3782 if (adj->op == IPA_PARM_OP_COPY)
3784 if (care_for_types)
3785 new_arg_types = tree_cons (NULL_TREE, otypes[adj->base_index],
3786 new_arg_types);
3787 *link = parm;
3788 link = &DECL_CHAIN (parm);
3790 else if (adj->op != IPA_PARM_OP_REMOVE)
3792 tree new_parm;
3793 tree ptype;
3795 if (adj->by_ref)
3796 ptype = build_pointer_type (adj->type);
3797 else
3799 ptype = adj->type;
3800 if (is_gimple_reg_type (ptype))
3802 unsigned malign = GET_MODE_ALIGNMENT (TYPE_MODE (ptype));
3803 if (TYPE_ALIGN (ptype) < malign)
3804 ptype = build_aligned_type (ptype, malign);
3808 if (care_for_types)
3809 new_arg_types = tree_cons (NULL_TREE, ptype, new_arg_types);
3811 new_parm = build_decl (UNKNOWN_LOCATION, PARM_DECL, NULL_TREE,
3812 ptype);
3813 const char *prefix = adj->arg_prefix ? adj->arg_prefix : "SYNTH";
3814 DECL_NAME (new_parm) = create_tmp_var_name (prefix);
3815 DECL_ARTIFICIAL (new_parm) = 1;
3816 DECL_ARG_TYPE (new_parm) = ptype;
3817 DECL_CONTEXT (new_parm) = fndecl;
3818 TREE_USED (new_parm) = 1;
3819 DECL_IGNORED_P (new_parm) = 1;
3820 layout_decl (new_parm, 0);
3822 if (adj->op == IPA_PARM_OP_NEW)
3823 adj->base = NULL;
3824 else
3825 adj->base = parm;
3826 adj->new_decl = new_parm;
3828 *link = new_parm;
3829 link = &DECL_CHAIN (new_parm);
3833 *link = NULL_TREE;
3835 tree new_reversed = NULL;
3836 if (care_for_types)
3838 new_reversed = nreverse (new_arg_types);
3839 if (last_parm_void)
3841 if (new_reversed)
3842 TREE_CHAIN (new_arg_types) = void_list_node;
3843 else
3844 new_reversed = void_list_node;
3848 /* Use copy_node to preserve as much as possible from original type
3849 (debug info, attribute lists etc.)
3850 Exception is METHOD_TYPEs must have THIS argument.
3851 When we are asked to remove it, we need to build new FUNCTION_TYPE
3852 instead. */
3853 tree new_type = NULL;
3854 if (TREE_CODE (orig_type) != METHOD_TYPE
3855 || (adjustments[0].op == IPA_PARM_OP_COPY
3856 && adjustments[0].base_index == 0))
3858 new_type = build_distinct_type_copy (orig_type);
3859 TYPE_ARG_TYPES (new_type) = new_reversed;
3861 else
3863 new_type
3864 = build_distinct_type_copy (build_function_type (TREE_TYPE (orig_type),
3865 new_reversed));
3866 TYPE_CONTEXT (new_type) = TYPE_CONTEXT (orig_type);
3867 DECL_VINDEX (fndecl) = NULL_TREE;
3870 /* When signature changes, we need to clear builtin info. */
3871 if (DECL_BUILT_IN (fndecl))
3873 DECL_BUILT_IN_CLASS (fndecl) = NOT_BUILT_IN;
3874 DECL_FUNCTION_CODE (fndecl) = (enum built_in_function) 0;
3877 TREE_TYPE (fndecl) = new_type;
3878 DECL_VIRTUAL_P (fndecl) = 0;
3879 DECL_LANG_SPECIFIC (fndecl) = NULL;
3880 otypes.release ();
3881 oparms.release ();
3884 /* Modify actual arguments of a function call CS as indicated in ADJUSTMENTS.
3885 If this is a directly recursive call, CS must be NULL. Otherwise it must
3886 contain the corresponding call graph edge. */
3888 void
3889 ipa_modify_call_arguments (struct cgraph_edge *cs, gcall *stmt,
3890 ipa_parm_adjustment_vec adjustments)
3892 struct cgraph_node *current_node = cgraph_node::get (current_function_decl);
3893 vec<tree> vargs;
3894 vec<tree, va_gc> **debug_args = NULL;
3895 gcall *new_stmt;
3896 gimple_stmt_iterator gsi, prev_gsi;
3897 tree callee_decl;
3898 int i, len;
3900 len = adjustments.length ();
3901 vargs.create (len);
3902 callee_decl = !cs ? gimple_call_fndecl (stmt) : cs->callee->decl;
3903 current_node->remove_stmt_references (stmt);
3905 gsi = gsi_for_stmt (stmt);
3906 prev_gsi = gsi;
3907 gsi_prev (&prev_gsi);
3908 for (i = 0; i < len; i++)
3910 struct ipa_parm_adjustment *adj;
3912 adj = &adjustments[i];
3914 if (adj->op == IPA_PARM_OP_COPY)
3916 tree arg = gimple_call_arg (stmt, adj->base_index);
3918 vargs.quick_push (arg);
3920 else if (adj->op != IPA_PARM_OP_REMOVE)
3922 tree expr, base, off;
3923 location_t loc;
3924 unsigned int deref_align = 0;
3925 bool deref_base = false;
3927 /* We create a new parameter out of the value of the old one, we can
3928 do the following kind of transformations:
3930 - A scalar passed by reference is converted to a scalar passed by
3931 value. (adj->by_ref is false and the type of the original
3932 actual argument is a pointer to a scalar).
3934 - A part of an aggregate is passed instead of the whole aggregate.
3935 The part can be passed either by value or by reference, this is
3936 determined by value of adj->by_ref. Moreover, the code below
3937 handles both situations when the original aggregate is passed by
3938 value (its type is not a pointer) and when it is passed by
3939 reference (it is a pointer to an aggregate).
3941 When the new argument is passed by reference (adj->by_ref is true)
3942 it must be a part of an aggregate and therefore we form it by
3943 simply taking the address of a reference inside the original
3944 aggregate. */
3946 gcc_checking_assert (adj->offset % BITS_PER_UNIT == 0);
3947 base = gimple_call_arg (stmt, adj->base_index);
3948 loc = DECL_P (base) ? DECL_SOURCE_LOCATION (base)
3949 : EXPR_LOCATION (base);
3951 if (TREE_CODE (base) != ADDR_EXPR
3952 && POINTER_TYPE_P (TREE_TYPE (base)))
3953 off = build_int_cst (adj->alias_ptr_type,
3954 adj->offset / BITS_PER_UNIT);
3955 else
3957 HOST_WIDE_INT base_offset;
3958 tree prev_base;
3959 bool addrof;
3961 if (TREE_CODE (base) == ADDR_EXPR)
3963 base = TREE_OPERAND (base, 0);
3964 addrof = true;
3966 else
3967 addrof = false;
3968 prev_base = base;
3969 base = get_addr_base_and_unit_offset (base, &base_offset);
3970 /* Aggregate arguments can have non-invariant addresses. */
3971 if (!base)
3973 base = build_fold_addr_expr (prev_base);
3974 off = build_int_cst (adj->alias_ptr_type,
3975 adj->offset / BITS_PER_UNIT);
3977 else if (TREE_CODE (base) == MEM_REF)
3979 if (!addrof)
3981 deref_base = true;
3982 deref_align = TYPE_ALIGN (TREE_TYPE (base));
3984 off = build_int_cst (adj->alias_ptr_type,
3985 base_offset
3986 + adj->offset / BITS_PER_UNIT);
3987 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1),
3988 off);
3989 base = TREE_OPERAND (base, 0);
3991 else
3993 off = build_int_cst (adj->alias_ptr_type,
3994 base_offset
3995 + adj->offset / BITS_PER_UNIT);
3996 base = build_fold_addr_expr (base);
4000 if (!adj->by_ref)
4002 tree type = adj->type;
4003 unsigned int align;
4004 unsigned HOST_WIDE_INT misalign;
4006 if (deref_base)
4008 align = deref_align;
4009 misalign = 0;
4011 else
4013 get_pointer_alignment_1 (base, &align, &misalign);
4014 if (TYPE_ALIGN (type) > align)
4015 align = TYPE_ALIGN (type);
4017 misalign += (offset_int::from (off, SIGNED).to_short_addr ()
4018 * BITS_PER_UNIT);
4019 misalign = misalign & (align - 1);
4020 if (misalign != 0)
4021 align = (misalign & -misalign);
4022 if (align < TYPE_ALIGN (type))
4023 type = build_aligned_type (type, align);
4024 base = force_gimple_operand_gsi (&gsi, base,
4025 true, NULL, true, GSI_SAME_STMT);
4026 expr = fold_build2_loc (loc, MEM_REF, type, base, off);
4027 /* If expr is not a valid gimple call argument emit
4028 a load into a temporary. */
4029 if (is_gimple_reg_type (TREE_TYPE (expr)))
4031 gimple tem = gimple_build_assign (NULL_TREE, expr);
4032 if (gimple_in_ssa_p (cfun))
4034 gimple_set_vuse (tem, gimple_vuse (stmt));
4035 expr = make_ssa_name (TREE_TYPE (expr), tem);
4037 else
4038 expr = create_tmp_reg (TREE_TYPE (expr));
4039 gimple_assign_set_lhs (tem, expr);
4040 gsi_insert_before (&gsi, tem, GSI_SAME_STMT);
4043 else
4045 expr = fold_build2_loc (loc, MEM_REF, adj->type, base, off);
4046 expr = build_fold_addr_expr (expr);
4047 expr = force_gimple_operand_gsi (&gsi, expr,
4048 true, NULL, true, GSI_SAME_STMT);
4050 vargs.quick_push (expr);
4052 if (adj->op != IPA_PARM_OP_COPY && MAY_HAVE_DEBUG_STMTS)
4054 unsigned int ix;
4055 tree ddecl = NULL_TREE, origin = DECL_ORIGIN (adj->base), arg;
4056 gimple def_temp;
4058 arg = gimple_call_arg (stmt, adj->base_index);
4059 if (!useless_type_conversion_p (TREE_TYPE (origin), TREE_TYPE (arg)))
4061 if (!fold_convertible_p (TREE_TYPE (origin), arg))
4062 continue;
4063 arg = fold_convert_loc (gimple_location (stmt),
4064 TREE_TYPE (origin), arg);
4066 if (debug_args == NULL)
4067 debug_args = decl_debug_args_insert (callee_decl);
4068 for (ix = 0; vec_safe_iterate (*debug_args, ix, &ddecl); ix += 2)
4069 if (ddecl == origin)
4071 ddecl = (**debug_args)[ix + 1];
4072 break;
4074 if (ddecl == NULL)
4076 ddecl = make_node (DEBUG_EXPR_DECL);
4077 DECL_ARTIFICIAL (ddecl) = 1;
4078 TREE_TYPE (ddecl) = TREE_TYPE (origin);
4079 DECL_MODE (ddecl) = DECL_MODE (origin);
4081 vec_safe_push (*debug_args, origin);
4082 vec_safe_push (*debug_args, ddecl);
4084 def_temp = gimple_build_debug_bind (ddecl, unshare_expr (arg), stmt);
4085 gsi_insert_before (&gsi, def_temp, GSI_SAME_STMT);
4089 if (dump_file && (dump_flags & TDF_DETAILS))
4091 fprintf (dump_file, "replacing stmt:");
4092 print_gimple_stmt (dump_file, gsi_stmt (gsi), 0, 0);
4095 new_stmt = gimple_build_call_vec (callee_decl, vargs);
4096 vargs.release ();
4097 if (gimple_call_lhs (stmt))
4098 gimple_call_set_lhs (new_stmt, gimple_call_lhs (stmt));
4100 gimple_set_block (new_stmt, gimple_block (stmt));
4101 if (gimple_has_location (stmt))
4102 gimple_set_location (new_stmt, gimple_location (stmt));
4103 gimple_call_set_chain (new_stmt, gimple_call_chain (stmt));
4104 gimple_call_copy_flags (new_stmt, stmt);
4105 if (gimple_in_ssa_p (cfun))
4107 gimple_set_vuse (new_stmt, gimple_vuse (stmt));
4108 if (gimple_vdef (stmt))
4110 gimple_set_vdef (new_stmt, gimple_vdef (stmt));
4111 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
4115 if (dump_file && (dump_flags & TDF_DETAILS))
4117 fprintf (dump_file, "with stmt:");
4118 print_gimple_stmt (dump_file, new_stmt, 0, 0);
4119 fprintf (dump_file, "\n");
4121 gsi_replace (&gsi, new_stmt, true);
4122 if (cs)
4123 cs->set_call_stmt (new_stmt);
4126 current_node->record_stmt_references (gsi_stmt (gsi));
4127 gsi_prev (&gsi);
4129 while (gsi_stmt (gsi) != gsi_stmt (prev_gsi));
4132 /* If the expression *EXPR should be replaced by a reduction of a parameter, do
4133 so. ADJUSTMENTS is a pointer to a vector of adjustments. CONVERT
4134 specifies whether the function should care about type incompatibility the
4135 current and new expressions. If it is false, the function will leave
4136 incompatibility issues to the caller. Return true iff the expression
4137 was modified. */
4139 bool
4140 ipa_modify_expr (tree *expr, bool convert,
4141 ipa_parm_adjustment_vec adjustments)
4143 struct ipa_parm_adjustment *cand
4144 = ipa_get_adjustment_candidate (&expr, &convert, adjustments, false);
4145 if (!cand)
4146 return false;
4148 tree src;
4149 if (cand->by_ref)
4150 src = build_simple_mem_ref (cand->new_decl);
4151 else
4152 src = cand->new_decl;
4154 if (dump_file && (dump_flags & TDF_DETAILS))
4156 fprintf (dump_file, "About to replace expr ");
4157 print_generic_expr (dump_file, *expr, 0);
4158 fprintf (dump_file, " with ");
4159 print_generic_expr (dump_file, src, 0);
4160 fprintf (dump_file, "\n");
4163 if (convert && !useless_type_conversion_p (TREE_TYPE (*expr), cand->type))
4165 tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*expr), src);
4166 *expr = vce;
4168 else
4169 *expr = src;
4170 return true;
4173 /* If T is an SSA_NAME, return NULL if it is not a default def or
4174 return its base variable if it is. If IGNORE_DEFAULT_DEF is true,
4175 the base variable is always returned, regardless if it is a default
4176 def. Return T if it is not an SSA_NAME. */
4178 static tree
4179 get_ssa_base_param (tree t, bool ignore_default_def)
4181 if (TREE_CODE (t) == SSA_NAME)
4183 if (ignore_default_def || SSA_NAME_IS_DEFAULT_DEF (t))
4184 return SSA_NAME_VAR (t);
4185 else
4186 return NULL_TREE;
4188 return t;
4191 /* Given an expression, return an adjustment entry specifying the
4192 transformation to be done on EXPR. If no suitable adjustment entry
4193 was found, returns NULL.
4195 If IGNORE_DEFAULT_DEF is set, consider SSA_NAMEs which are not a
4196 default def, otherwise bail on them.
4198 If CONVERT is non-NULL, this function will set *CONVERT if the
4199 expression provided is a component reference. ADJUSTMENTS is the
4200 adjustments vector. */
4202 ipa_parm_adjustment *
4203 ipa_get_adjustment_candidate (tree **expr, bool *convert,
4204 ipa_parm_adjustment_vec adjustments,
4205 bool ignore_default_def)
4207 if (TREE_CODE (**expr) == BIT_FIELD_REF
4208 || TREE_CODE (**expr) == IMAGPART_EXPR
4209 || TREE_CODE (**expr) == REALPART_EXPR)
4211 *expr = &TREE_OPERAND (**expr, 0);
4212 if (convert)
4213 *convert = true;
4216 HOST_WIDE_INT offset, size, max_size;
4217 tree base = get_ref_base_and_extent (**expr, &offset, &size, &max_size);
4218 if (!base || size == -1 || max_size == -1)
4219 return NULL;
4221 if (TREE_CODE (base) == MEM_REF)
4223 offset += mem_ref_offset (base).to_short_addr () * BITS_PER_UNIT;
4224 base = TREE_OPERAND (base, 0);
4227 base = get_ssa_base_param (base, ignore_default_def);
4228 if (!base || TREE_CODE (base) != PARM_DECL)
4229 return NULL;
4231 struct ipa_parm_adjustment *cand = NULL;
4232 unsigned int len = adjustments.length ();
4233 for (unsigned i = 0; i < len; i++)
4235 struct ipa_parm_adjustment *adj = &adjustments[i];
4237 if (adj->base == base
4238 && (adj->offset == offset || adj->op == IPA_PARM_OP_REMOVE))
4240 cand = adj;
4241 break;
4245 if (!cand || cand->op == IPA_PARM_OP_COPY || cand->op == IPA_PARM_OP_REMOVE)
4246 return NULL;
4247 return cand;
4250 /* Return true iff BASE_INDEX is in ADJUSTMENTS more than once. */
4252 static bool
4253 index_in_adjustments_multiple_times_p (int base_index,
4254 ipa_parm_adjustment_vec adjustments)
4256 int i, len = adjustments.length ();
4257 bool one = false;
4259 for (i = 0; i < len; i++)
4261 struct ipa_parm_adjustment *adj;
4262 adj = &adjustments[i];
4264 if (adj->base_index == base_index)
4266 if (one)
4267 return true;
4268 else
4269 one = true;
4272 return false;
4276 /* Return adjustments that should have the same effect on function parameters
4277 and call arguments as if they were first changed according to adjustments in
4278 INNER and then by adjustments in OUTER. */
4280 ipa_parm_adjustment_vec
4281 ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
4282 ipa_parm_adjustment_vec outer)
4284 int i, outlen = outer.length ();
4285 int inlen = inner.length ();
4286 int removals = 0;
4287 ipa_parm_adjustment_vec adjustments, tmp;
4289 tmp.create (inlen);
4290 for (i = 0; i < inlen; i++)
4292 struct ipa_parm_adjustment *n;
4293 n = &inner[i];
4295 if (n->op == IPA_PARM_OP_REMOVE)
4296 removals++;
4297 else
4299 /* FIXME: Handling of new arguments are not implemented yet. */
4300 gcc_assert (n->op != IPA_PARM_OP_NEW);
4301 tmp.quick_push (*n);
4305 adjustments.create (outlen + removals);
4306 for (i = 0; i < outlen; i++)
4308 struct ipa_parm_adjustment r;
4309 struct ipa_parm_adjustment *out = &outer[i];
4310 struct ipa_parm_adjustment *in = &tmp[out->base_index];
4312 memset (&r, 0, sizeof (r));
4313 gcc_assert (in->op != IPA_PARM_OP_REMOVE);
4314 if (out->op == IPA_PARM_OP_REMOVE)
4316 if (!index_in_adjustments_multiple_times_p (in->base_index, tmp))
4318 r.op = IPA_PARM_OP_REMOVE;
4319 adjustments.quick_push (r);
4321 continue;
4323 else
4325 /* FIXME: Handling of new arguments are not implemented yet. */
4326 gcc_assert (out->op != IPA_PARM_OP_NEW);
4329 r.base_index = in->base_index;
4330 r.type = out->type;
4332 /* FIXME: Create nonlocal value too. */
4334 if (in->op == IPA_PARM_OP_COPY && out->op == IPA_PARM_OP_COPY)
4335 r.op = IPA_PARM_OP_COPY;
4336 else if (in->op == IPA_PARM_OP_COPY)
4337 r.offset = out->offset;
4338 else if (out->op == IPA_PARM_OP_COPY)
4339 r.offset = in->offset;
4340 else
4341 r.offset = in->offset + out->offset;
4342 adjustments.quick_push (r);
4345 for (i = 0; i < inlen; i++)
4347 struct ipa_parm_adjustment *n = &inner[i];
4349 if (n->op == IPA_PARM_OP_REMOVE)
4350 adjustments.quick_push (*n);
4353 tmp.release ();
4354 return adjustments;
4357 /* Dump the adjustments in the vector ADJUSTMENTS to dump_file in a human
4358 friendly way, assuming they are meant to be applied to FNDECL. */
4360 void
4361 ipa_dump_param_adjustments (FILE *file, ipa_parm_adjustment_vec adjustments,
4362 tree fndecl)
4364 int i, len = adjustments.length ();
4365 bool first = true;
4366 vec<tree> parms = ipa_get_vector_of_formal_parms (fndecl);
4368 fprintf (file, "IPA param adjustments: ");
4369 for (i = 0; i < len; i++)
4371 struct ipa_parm_adjustment *adj;
4372 adj = &adjustments[i];
4374 if (!first)
4375 fprintf (file, " ");
4376 else
4377 first = false;
4379 fprintf (file, "%i. base_index: %i - ", i, adj->base_index);
4380 print_generic_expr (file, parms[adj->base_index], 0);
4381 if (adj->base)
4383 fprintf (file, ", base: ");
4384 print_generic_expr (file, adj->base, 0);
4386 if (adj->new_decl)
4388 fprintf (file, ", new_decl: ");
4389 print_generic_expr (file, adj->new_decl, 0);
4391 if (adj->new_ssa_base)
4393 fprintf (file, ", new_ssa_base: ");
4394 print_generic_expr (file, adj->new_ssa_base, 0);
4397 if (adj->op == IPA_PARM_OP_COPY)
4398 fprintf (file, ", copy_param");
4399 else if (adj->op == IPA_PARM_OP_REMOVE)
4400 fprintf (file, ", remove_param");
4401 else
4402 fprintf (file, ", offset %li", (long) adj->offset);
4403 if (adj->by_ref)
4404 fprintf (file, ", by_ref");
4405 print_node_brief (file, ", type: ", adj->type, 0);
4406 fprintf (file, "\n");
4408 parms.release ();
4411 /* Dump the AV linked list. */
4413 void
4414 ipa_dump_agg_replacement_values (FILE *f, struct ipa_agg_replacement_value *av)
4416 bool comma = false;
4417 fprintf (f, " Aggregate replacements:");
4418 for (; av; av = av->next)
4420 fprintf (f, "%s %i[" HOST_WIDE_INT_PRINT_DEC "]=", comma ? "," : "",
4421 av->index, av->offset);
4422 print_generic_expr (f, av->value, 0);
4423 comma = true;
4425 fprintf (f, "\n");
4428 /* Stream out jump function JUMP_FUNC to OB. */
4430 static void
4431 ipa_write_jump_function (struct output_block *ob,
4432 struct ipa_jump_func *jump_func)
4434 struct ipa_agg_jf_item *item;
4435 struct bitpack_d bp;
4436 int i, count;
4438 streamer_write_uhwi (ob, jump_func->type);
4439 switch (jump_func->type)
4441 case IPA_JF_UNKNOWN:
4442 break;
4443 case IPA_JF_CONST:
4444 gcc_assert (
4445 EXPR_LOCATION (jump_func->value.constant.value) == UNKNOWN_LOCATION);
4446 stream_write_tree (ob, jump_func->value.constant.value, true);
4447 break;
4448 case IPA_JF_PASS_THROUGH:
4449 streamer_write_uhwi (ob, jump_func->value.pass_through.operation);
4450 if (jump_func->value.pass_through.operation == NOP_EXPR)
4452 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4453 bp = bitpack_create (ob->main_stream);
4454 bp_pack_value (&bp, jump_func->value.pass_through.agg_preserved, 1);
4455 streamer_write_bitpack (&bp);
4457 else
4459 stream_write_tree (ob, jump_func->value.pass_through.operand, true);
4460 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4462 break;
4463 case IPA_JF_ANCESTOR:
4464 streamer_write_uhwi (ob, jump_func->value.ancestor.offset);
4465 streamer_write_uhwi (ob, jump_func->value.ancestor.formal_id);
4466 bp = bitpack_create (ob->main_stream);
4467 bp_pack_value (&bp, jump_func->value.ancestor.agg_preserved, 1);
4468 streamer_write_bitpack (&bp);
4469 break;
4472 count = vec_safe_length (jump_func->agg.items);
4473 streamer_write_uhwi (ob, count);
4474 if (count)
4476 bp = bitpack_create (ob->main_stream);
4477 bp_pack_value (&bp, jump_func->agg.by_ref, 1);
4478 streamer_write_bitpack (&bp);
4481 FOR_EACH_VEC_SAFE_ELT (jump_func->agg.items, i, item)
4483 streamer_write_uhwi (ob, item->offset);
4484 stream_write_tree (ob, item->value, true);
4487 bp = bitpack_create (ob->main_stream);
4488 bp_pack_value (&bp, jump_func->alignment.known, 1);
4489 streamer_write_bitpack (&bp);
4490 if (jump_func->alignment.known)
4492 streamer_write_uhwi (ob, jump_func->alignment.align);
4493 streamer_write_uhwi (ob, jump_func->alignment.misalign);
4497 /* Read in jump function JUMP_FUNC from IB. */
4499 static void
4500 ipa_read_jump_function (struct lto_input_block *ib,
4501 struct ipa_jump_func *jump_func,
4502 struct cgraph_edge *cs,
4503 struct data_in *data_in)
4505 enum jump_func_type jftype;
4506 enum tree_code operation;
4507 int i, count;
4509 jftype = (enum jump_func_type) streamer_read_uhwi (ib);
4510 switch (jftype)
4512 case IPA_JF_UNKNOWN:
4513 ipa_set_jf_unknown (jump_func);
4514 break;
4515 case IPA_JF_CONST:
4516 ipa_set_jf_constant (jump_func, stream_read_tree (ib, data_in), cs);
4517 break;
4518 case IPA_JF_PASS_THROUGH:
4519 operation = (enum tree_code) streamer_read_uhwi (ib);
4520 if (operation == NOP_EXPR)
4522 int formal_id = streamer_read_uhwi (ib);
4523 struct bitpack_d bp = streamer_read_bitpack (ib);
4524 bool agg_preserved = bp_unpack_value (&bp, 1);
4525 ipa_set_jf_simple_pass_through (jump_func, formal_id, agg_preserved);
4527 else
4529 tree operand = stream_read_tree (ib, data_in);
4530 int formal_id = streamer_read_uhwi (ib);
4531 ipa_set_jf_arith_pass_through (jump_func, formal_id, operand,
4532 operation);
4534 break;
4535 case IPA_JF_ANCESTOR:
4537 HOST_WIDE_INT offset = streamer_read_uhwi (ib);
4538 int formal_id = streamer_read_uhwi (ib);
4539 struct bitpack_d bp = streamer_read_bitpack (ib);
4540 bool agg_preserved = bp_unpack_value (&bp, 1);
4541 ipa_set_ancestor_jf (jump_func, offset, formal_id, agg_preserved);
4542 break;
4546 count = streamer_read_uhwi (ib);
4547 vec_alloc (jump_func->agg.items, count);
4548 if (count)
4550 struct bitpack_d bp = streamer_read_bitpack (ib);
4551 jump_func->agg.by_ref = bp_unpack_value (&bp, 1);
4553 for (i = 0; i < count; i++)
4555 struct ipa_agg_jf_item item;
4556 item.offset = streamer_read_uhwi (ib);
4557 item.value = stream_read_tree (ib, data_in);
4558 jump_func->agg.items->quick_push (item);
4561 struct bitpack_d bp = streamer_read_bitpack (ib);
4562 bool alignment_known = bp_unpack_value (&bp, 1);
4563 if (alignment_known)
4565 jump_func->alignment.known = true;
4566 jump_func->alignment.align = streamer_read_uhwi (ib);
4567 jump_func->alignment.misalign = streamer_read_uhwi (ib);
4569 else
4570 jump_func->alignment.known = false;
4573 /* Stream out parts of cgraph_indirect_call_info corresponding to CS that are
4574 relevant to indirect inlining to OB. */
4576 static void
4577 ipa_write_indirect_edge_info (struct output_block *ob,
4578 struct cgraph_edge *cs)
4580 struct cgraph_indirect_call_info *ii = cs->indirect_info;
4581 struct bitpack_d bp;
4583 streamer_write_hwi (ob, ii->param_index);
4584 bp = bitpack_create (ob->main_stream);
4585 bp_pack_value (&bp, ii->polymorphic, 1);
4586 bp_pack_value (&bp, ii->agg_contents, 1);
4587 bp_pack_value (&bp, ii->member_ptr, 1);
4588 bp_pack_value (&bp, ii->by_ref, 1);
4589 bp_pack_value (&bp, ii->vptr_changed, 1);
4590 streamer_write_bitpack (&bp);
4591 if (ii->agg_contents || ii->polymorphic)
4592 streamer_write_hwi (ob, ii->offset);
4593 else
4594 gcc_assert (ii->offset == 0);
4596 if (ii->polymorphic)
4598 streamer_write_hwi (ob, ii->otr_token);
4599 stream_write_tree (ob, ii->otr_type, true);
4600 ii->context.stream_out (ob);
4604 /* Read in parts of cgraph_indirect_call_info corresponding to CS that are
4605 relevant to indirect inlining from IB. */
4607 static void
4608 ipa_read_indirect_edge_info (struct lto_input_block *ib,
4609 struct data_in *data_in,
4610 struct cgraph_edge *cs)
4612 struct cgraph_indirect_call_info *ii = cs->indirect_info;
4613 struct bitpack_d bp;
4615 ii->param_index = (int) streamer_read_hwi (ib);
4616 bp = streamer_read_bitpack (ib);
4617 ii->polymorphic = bp_unpack_value (&bp, 1);
4618 ii->agg_contents = bp_unpack_value (&bp, 1);
4619 ii->member_ptr = bp_unpack_value (&bp, 1);
4620 ii->by_ref = bp_unpack_value (&bp, 1);
4621 ii->vptr_changed = bp_unpack_value (&bp, 1);
4622 if (ii->agg_contents || ii->polymorphic)
4623 ii->offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
4624 else
4625 ii->offset = 0;
4626 if (ii->polymorphic)
4628 ii->otr_token = (HOST_WIDE_INT) streamer_read_hwi (ib);
4629 ii->otr_type = stream_read_tree (ib, data_in);
4630 ii->context.stream_in (ib, data_in);
4634 /* Stream out NODE info to OB. */
4636 static void
4637 ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
4639 int node_ref;
4640 lto_symtab_encoder_t encoder;
4641 struct ipa_node_params *info = IPA_NODE_REF (node);
4642 int j;
4643 struct cgraph_edge *e;
4644 struct bitpack_d bp;
4646 encoder = ob->decl_state->symtab_node_encoder;
4647 node_ref = lto_symtab_encoder_encode (encoder, node);
4648 streamer_write_uhwi (ob, node_ref);
4650 streamer_write_uhwi (ob, ipa_get_param_count (info));
4651 for (j = 0; j < ipa_get_param_count (info); j++)
4652 streamer_write_uhwi (ob, ipa_get_param_move_cost (info, j));
4653 bp = bitpack_create (ob->main_stream);
4654 gcc_assert (info->analysis_done
4655 || ipa_get_param_count (info) == 0);
4656 gcc_assert (!info->node_enqueued);
4657 gcc_assert (!info->ipcp_orig_node);
4658 for (j = 0; j < ipa_get_param_count (info); j++)
4659 bp_pack_value (&bp, ipa_is_param_used (info, j), 1);
4660 streamer_write_bitpack (&bp);
4661 for (j = 0; j < ipa_get_param_count (info); j++)
4662 streamer_write_hwi (ob, ipa_get_controlled_uses (info, j));
4663 for (e = node->callees; e; e = e->next_callee)
4665 struct ipa_edge_args *args = IPA_EDGE_REF (e);
4667 streamer_write_uhwi (ob,
4668 ipa_get_cs_argument_count (args) * 2
4669 + (args->polymorphic_call_contexts != NULL));
4670 for (j = 0; j < ipa_get_cs_argument_count (args); j++)
4672 ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
4673 if (args->polymorphic_call_contexts != NULL)
4674 ipa_get_ith_polymorhic_call_context (args, j)->stream_out (ob);
4677 for (e = node->indirect_calls; e; e = e->next_callee)
4679 struct ipa_edge_args *args = IPA_EDGE_REF (e);
4681 streamer_write_uhwi (ob,
4682 ipa_get_cs_argument_count (args) * 2
4683 + (args->polymorphic_call_contexts != NULL));
4684 for (j = 0; j < ipa_get_cs_argument_count (args); j++)
4686 ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
4687 if (args->polymorphic_call_contexts != NULL)
4688 ipa_get_ith_polymorhic_call_context (args, j)->stream_out (ob);
4690 ipa_write_indirect_edge_info (ob, e);
4694 /* Stream in NODE info from IB. */
4696 static void
4697 ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
4698 struct data_in *data_in)
4700 struct ipa_node_params *info = IPA_NODE_REF (node);
4701 int k;
4702 struct cgraph_edge *e;
4703 struct bitpack_d bp;
4705 ipa_alloc_node_params (node, streamer_read_uhwi (ib));
4707 for (k = 0; k < ipa_get_param_count (info); k++)
4708 info->descriptors[k].move_cost = streamer_read_uhwi (ib);
4710 bp = streamer_read_bitpack (ib);
4711 if (ipa_get_param_count (info) != 0)
4712 info->analysis_done = true;
4713 info->node_enqueued = false;
4714 for (k = 0; k < ipa_get_param_count (info); k++)
4715 ipa_set_param_used (info, k, bp_unpack_value (&bp, 1));
4716 for (k = 0; k < ipa_get_param_count (info); k++)
4717 ipa_set_controlled_uses (info, k, streamer_read_hwi (ib));
4718 for (e = node->callees; e; e = e->next_callee)
4720 struct ipa_edge_args *args = IPA_EDGE_REF (e);
4721 int count = streamer_read_uhwi (ib);
4722 bool contexts_computed = count & 1;
4723 count /= 2;
4725 if (!count)
4726 continue;
4727 vec_safe_grow_cleared (args->jump_functions, count);
4728 if (contexts_computed)
4729 vec_safe_grow_cleared (args->polymorphic_call_contexts, count);
4731 for (k = 0; k < ipa_get_cs_argument_count (args); k++)
4733 ipa_read_jump_function (ib, ipa_get_ith_jump_func (args, k), e,
4734 data_in);
4735 if (contexts_computed)
4736 ipa_get_ith_polymorhic_call_context (args, k)->stream_in (ib, data_in);
4739 for (e = node->indirect_calls; e; e = e->next_callee)
4741 struct ipa_edge_args *args = IPA_EDGE_REF (e);
4742 int count = streamer_read_uhwi (ib);
4743 bool contexts_computed = count & 1;
4744 count /= 2;
4746 if (count)
4748 vec_safe_grow_cleared (args->jump_functions, count);
4749 if (contexts_computed)
4750 vec_safe_grow_cleared (args->polymorphic_call_contexts, count);
4751 for (k = 0; k < ipa_get_cs_argument_count (args); k++)
4753 ipa_read_jump_function (ib, ipa_get_ith_jump_func (args, k), e,
4754 data_in);
4755 if (contexts_computed)
4756 ipa_get_ith_polymorhic_call_context (args, k)->stream_in (ib, data_in);
4759 ipa_read_indirect_edge_info (ib, data_in, e);
4763 /* Write jump functions for nodes in SET. */
4765 void
4766 ipa_prop_write_jump_functions (void)
4768 struct cgraph_node *node;
4769 struct output_block *ob;
4770 unsigned int count = 0;
4771 lto_symtab_encoder_iterator lsei;
4772 lto_symtab_encoder_t encoder;
4774 if (!ipa_node_params_sum)
4775 return;
4777 ob = create_output_block (LTO_section_jump_functions);
4778 encoder = ob->decl_state->symtab_node_encoder;
4779 ob->symbol = NULL;
4780 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
4781 lsei_next_function_in_partition (&lsei))
4783 node = lsei_cgraph_node (lsei);
4784 if (node->has_gimple_body_p ()
4785 && IPA_NODE_REF (node) != NULL)
4786 count++;
4789 streamer_write_uhwi (ob, count);
4791 /* Process all of the functions. */
4792 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
4793 lsei_next_function_in_partition (&lsei))
4795 node = lsei_cgraph_node (lsei);
4796 if (node->has_gimple_body_p ()
4797 && IPA_NODE_REF (node) != NULL)
4798 ipa_write_node_info (ob, node);
4800 streamer_write_char_stream (ob->main_stream, 0);
4801 produce_asm (ob, NULL);
4802 destroy_output_block (ob);
4805 /* Read section in file FILE_DATA of length LEN with data DATA. */
4807 static void
4808 ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
4809 size_t len)
4811 const struct lto_function_header *header =
4812 (const struct lto_function_header *) data;
4813 const int cfg_offset = sizeof (struct lto_function_header);
4814 const int main_offset = cfg_offset + header->cfg_size;
4815 const int string_offset = main_offset + header->main_size;
4816 struct data_in *data_in;
4817 unsigned int i;
4818 unsigned int count;
4820 lto_input_block ib_main ((const char *) data + main_offset,
4821 header->main_size);
4823 data_in =
4824 lto_data_in_create (file_data, (const char *) data + string_offset,
4825 header->string_size, vNULL);
4826 count = streamer_read_uhwi (&ib_main);
4828 for (i = 0; i < count; i++)
4830 unsigned int index;
4831 struct cgraph_node *node;
4832 lto_symtab_encoder_t encoder;
4834 index = streamer_read_uhwi (&ib_main);
4835 encoder = file_data->symtab_node_encoder;
4836 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
4837 index));
4838 gcc_assert (node->definition);
4839 ipa_read_node_info (&ib_main, node, data_in);
4841 lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
4842 len);
4843 lto_data_in_delete (data_in);
4846 /* Read ipcp jump functions. */
4848 void
4849 ipa_prop_read_jump_functions (void)
4851 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
4852 struct lto_file_decl_data *file_data;
4853 unsigned int j = 0;
4855 ipa_check_create_node_params ();
4856 ipa_check_create_edge_args ();
4857 ipa_register_cgraph_hooks ();
4859 while ((file_data = file_data_vec[j++]))
4861 size_t len;
4862 const char *data = lto_get_section_data (file_data, LTO_section_jump_functions, NULL, &len);
4864 if (data)
4865 ipa_prop_read_section (file_data, data, len);
4869 /* After merging units, we can get mismatch in argument counts.
4870 Also decl merging might've rendered parameter lists obsolete.
4871 Also compute called_with_variable_arg info. */
4873 void
4874 ipa_update_after_lto_read (void)
4876 ipa_check_create_node_params ();
4877 ipa_check_create_edge_args ();
4880 void
4881 write_ipcp_transformation_info (output_block *ob, cgraph_node *node)
4883 int node_ref;
4884 unsigned int count = 0;
4885 lto_symtab_encoder_t encoder;
4886 struct ipa_agg_replacement_value *aggvals, *av;
4888 aggvals = ipa_get_agg_replacements_for_node (node);
4889 encoder = ob->decl_state->symtab_node_encoder;
4890 node_ref = lto_symtab_encoder_encode (encoder, node);
4891 streamer_write_uhwi (ob, node_ref);
4893 for (av = aggvals; av; av = av->next)
4894 count++;
4895 streamer_write_uhwi (ob, count);
4897 for (av = aggvals; av; av = av->next)
4899 struct bitpack_d bp;
4901 streamer_write_uhwi (ob, av->offset);
4902 streamer_write_uhwi (ob, av->index);
4903 stream_write_tree (ob, av->value, true);
4905 bp = bitpack_create (ob->main_stream);
4906 bp_pack_value (&bp, av->by_ref, 1);
4907 streamer_write_bitpack (&bp);
4910 ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node);
4911 if (ts && vec_safe_length (ts->alignments) > 0)
4913 count = ts->alignments->length ();
4915 streamer_write_uhwi (ob, count);
4916 for (unsigned i = 0; i < count; ++i)
4918 ipa_alignment *parm_al = &(*ts->alignments)[i];
4920 struct bitpack_d bp;
4921 bp = bitpack_create (ob->main_stream);
4922 bp_pack_value (&bp, parm_al->known, 1);
4923 streamer_write_bitpack (&bp);
4924 if (parm_al->known)
4926 streamer_write_uhwi (ob, parm_al->align);
4927 streamer_write_hwi_in_range (ob->main_stream, 0, parm_al->align,
4928 parm_al->misalign);
4932 else
4933 streamer_write_uhwi (ob, 0);
4936 /* Stream in the aggregate value replacement chain for NODE from IB. */
4938 static void
4939 read_ipcp_transformation_info (lto_input_block *ib, cgraph_node *node,
4940 data_in *data_in)
4942 struct ipa_agg_replacement_value *aggvals = NULL;
4943 unsigned int count, i;
4945 count = streamer_read_uhwi (ib);
4946 for (i = 0; i <count; i++)
4948 struct ipa_agg_replacement_value *av;
4949 struct bitpack_d bp;
4951 av = ggc_alloc<ipa_agg_replacement_value> ();
4952 av->offset = streamer_read_uhwi (ib);
4953 av->index = streamer_read_uhwi (ib);
4954 av->value = stream_read_tree (ib, data_in);
4955 bp = streamer_read_bitpack (ib);
4956 av->by_ref = bp_unpack_value (&bp, 1);
4957 av->next = aggvals;
4958 aggvals = av;
4960 ipa_set_node_agg_value_chain (node, aggvals);
4962 count = streamer_read_uhwi (ib);
4963 if (count > 0)
4965 ipcp_grow_transformations_if_necessary ();
4967 ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node);
4968 vec_safe_grow_cleared (ts->alignments, count);
4970 for (i = 0; i < count; i++)
4972 ipa_alignment *parm_al;
4973 parm_al = &(*ts->alignments)[i];
4974 struct bitpack_d bp;
4975 bp = streamer_read_bitpack (ib);
4976 parm_al->known = bp_unpack_value (&bp, 1);
4977 if (parm_al->known)
4979 parm_al->align = streamer_read_uhwi (ib);
4980 parm_al->misalign
4981 = streamer_read_hwi_in_range (ib, "ipa-prop misalign",
4982 0, parm_al->align);
4988 /* Write all aggregate replacement for nodes in set. */
4990 void
4991 ipcp_write_transformation_summaries (void)
4993 struct cgraph_node *node;
4994 struct output_block *ob;
4995 unsigned int count = 0;
4996 lto_symtab_encoder_iterator lsei;
4997 lto_symtab_encoder_t encoder;
4999 ob = create_output_block (LTO_section_ipcp_transform);
5000 encoder = ob->decl_state->symtab_node_encoder;
5001 ob->symbol = NULL;
5002 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
5003 lsei_next_function_in_partition (&lsei))
5005 node = lsei_cgraph_node (lsei);
5006 if (node->has_gimple_body_p ())
5007 count++;
5010 streamer_write_uhwi (ob, count);
5012 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
5013 lsei_next_function_in_partition (&lsei))
5015 node = lsei_cgraph_node (lsei);
5016 if (node->has_gimple_body_p ())
5017 write_ipcp_transformation_info (ob, node);
5019 streamer_write_char_stream (ob->main_stream, 0);
5020 produce_asm (ob, NULL);
5021 destroy_output_block (ob);
5024 /* Read replacements section in file FILE_DATA of length LEN with data
5025 DATA. */
5027 static void
5028 read_replacements_section (struct lto_file_decl_data *file_data,
5029 const char *data,
5030 size_t len)
5032 const struct lto_function_header *header =
5033 (const struct lto_function_header *) data;
5034 const int cfg_offset = sizeof (struct lto_function_header);
5035 const int main_offset = cfg_offset + header->cfg_size;
5036 const int string_offset = main_offset + header->main_size;
5037 struct data_in *data_in;
5038 unsigned int i;
5039 unsigned int count;
5041 lto_input_block ib_main ((const char *) data + main_offset,
5042 header->main_size);
5044 data_in = lto_data_in_create (file_data, (const char *) data + string_offset,
5045 header->string_size, vNULL);
5046 count = streamer_read_uhwi (&ib_main);
5048 for (i = 0; i < count; i++)
5050 unsigned int index;
5051 struct cgraph_node *node;
5052 lto_symtab_encoder_t encoder;
5054 index = streamer_read_uhwi (&ib_main);
5055 encoder = file_data->symtab_node_encoder;
5056 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
5057 index));
5058 gcc_assert (node->definition);
5059 read_ipcp_transformation_info (&ib_main, node, data_in);
5061 lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
5062 len);
5063 lto_data_in_delete (data_in);
5066 /* Read IPA-CP aggregate replacements. */
5068 void
5069 ipcp_read_transformation_summaries (void)
5071 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
5072 struct lto_file_decl_data *file_data;
5073 unsigned int j = 0;
5075 while ((file_data = file_data_vec[j++]))
5077 size_t len;
5078 const char *data = lto_get_section_data (file_data,
5079 LTO_section_ipcp_transform,
5080 NULL, &len);
5081 if (data)
5082 read_replacements_section (file_data, data, len);
5086 /* Adjust the aggregate replacements in AGGVAL to reflect parameters skipped in
5087 NODE. */
5089 static void
5090 adjust_agg_replacement_values (struct cgraph_node *node,
5091 struct ipa_agg_replacement_value *aggval)
5093 struct ipa_agg_replacement_value *v;
5094 int i, c = 0, d = 0, *adj;
5096 if (!node->clone.combined_args_to_skip)
5097 return;
5099 for (v = aggval; v; v = v->next)
5101 gcc_assert (v->index >= 0);
5102 if (c < v->index)
5103 c = v->index;
5105 c++;
5107 adj = XALLOCAVEC (int, c);
5108 for (i = 0; i < c; i++)
5109 if (bitmap_bit_p (node->clone.combined_args_to_skip, i))
5111 adj[i] = -1;
5112 d++;
5114 else
5115 adj[i] = i - d;
5117 for (v = aggval; v; v = v->next)
5118 v->index = adj[v->index];
5121 /* Dominator walker driving the ipcp modification phase. */
5123 class ipcp_modif_dom_walker : public dom_walker
5125 public:
5126 ipcp_modif_dom_walker (struct func_body_info *fbi,
5127 vec<ipa_param_descriptor> descs,
5128 struct ipa_agg_replacement_value *av,
5129 bool *sc, bool *cc)
5130 : dom_walker (CDI_DOMINATORS), m_fbi (fbi), m_descriptors (descs),
5131 m_aggval (av), m_something_changed (sc), m_cfg_changed (cc) {}
5133 virtual void before_dom_children (basic_block);
5135 private:
5136 struct func_body_info *m_fbi;
5137 vec<ipa_param_descriptor> m_descriptors;
5138 struct ipa_agg_replacement_value *m_aggval;
5139 bool *m_something_changed, *m_cfg_changed;
5142 void
5143 ipcp_modif_dom_walker::before_dom_children (basic_block bb)
5145 gimple_stmt_iterator gsi;
5146 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
5148 struct ipa_agg_replacement_value *v;
5149 gimple stmt = gsi_stmt (gsi);
5150 tree rhs, val, t;
5151 HOST_WIDE_INT offset, size;
5152 int index;
5153 bool by_ref, vce;
5155 if (!gimple_assign_load_p (stmt))
5156 continue;
5157 rhs = gimple_assign_rhs1 (stmt);
5158 if (!is_gimple_reg_type (TREE_TYPE (rhs)))
5159 continue;
5161 vce = false;
5162 t = rhs;
5163 while (handled_component_p (t))
5165 /* V_C_E can do things like convert an array of integers to one
5166 bigger integer and similar things we do not handle below. */
5167 if (TREE_CODE (rhs) == VIEW_CONVERT_EXPR)
5169 vce = true;
5170 break;
5172 t = TREE_OPERAND (t, 0);
5174 if (vce)
5175 continue;
5177 if (!ipa_load_from_parm_agg_1 (m_fbi, m_descriptors, stmt, rhs, &index,
5178 &offset, &size, &by_ref))
5179 continue;
5180 for (v = m_aggval; v; v = v->next)
5181 if (v->index == index
5182 && v->offset == offset)
5183 break;
5184 if (!v
5185 || v->by_ref != by_ref
5186 || tree_to_shwi (TYPE_SIZE (TREE_TYPE (v->value))) != size)
5187 continue;
5189 gcc_checking_assert (is_gimple_ip_invariant (v->value));
5190 if (!useless_type_conversion_p (TREE_TYPE (rhs), TREE_TYPE (v->value)))
5192 if (fold_convertible_p (TREE_TYPE (rhs), v->value))
5193 val = fold_build1 (NOP_EXPR, TREE_TYPE (rhs), v->value);
5194 else if (TYPE_SIZE (TREE_TYPE (rhs))
5195 == TYPE_SIZE (TREE_TYPE (v->value)))
5196 val = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (rhs), v->value);
5197 else
5199 if (dump_file)
5201 fprintf (dump_file, " const ");
5202 print_generic_expr (dump_file, v->value, 0);
5203 fprintf (dump_file, " can't be converted to type of ");
5204 print_generic_expr (dump_file, rhs, 0);
5205 fprintf (dump_file, "\n");
5207 continue;
5210 else
5211 val = v->value;
5213 if (dump_file && (dump_flags & TDF_DETAILS))
5215 fprintf (dump_file, "Modifying stmt:\n ");
5216 print_gimple_stmt (dump_file, stmt, 0, 0);
5218 gimple_assign_set_rhs_from_tree (&gsi, val);
5219 update_stmt (stmt);
5221 if (dump_file && (dump_flags & TDF_DETAILS))
5223 fprintf (dump_file, "into:\n ");
5224 print_gimple_stmt (dump_file, stmt, 0, 0);
5225 fprintf (dump_file, "\n");
5228 *m_something_changed = true;
5229 if (maybe_clean_eh_stmt (stmt)
5230 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
5231 *m_cfg_changed = true;
5236 /* Update alignment of formal parameters as described in
5237 ipcp_transformation_summary. */
5239 static void
5240 ipcp_update_alignments (struct cgraph_node *node)
5242 tree fndecl = node->decl;
5243 tree parm = DECL_ARGUMENTS (fndecl);
5244 tree next_parm = parm;
5245 ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node);
5246 if (!ts || vec_safe_length (ts->alignments) == 0)
5247 return;
5248 const vec<ipa_alignment, va_gc> &alignments = *ts->alignments;
5249 unsigned count = alignments.length ();
5251 for (unsigned i = 0; i < count; ++i, parm = next_parm)
5253 if (node->clone.combined_args_to_skip
5254 && bitmap_bit_p (node->clone.combined_args_to_skip, i))
5255 continue;
5256 gcc_checking_assert (parm);
5257 next_parm = DECL_CHAIN (parm);
5259 if (!alignments[i].known || !is_gimple_reg (parm))
5260 continue;
5261 tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl), parm);
5262 if (!ddef)
5263 continue;
5265 if (dump_file)
5266 fprintf (dump_file, " Adjusting alignment of param %u to %u, "
5267 "misalignment to %u\n", i, alignments[i].align,
5268 alignments[i].misalign);
5270 struct ptr_info_def *pi = get_ptr_info (ddef);
5271 gcc_checking_assert (pi);
5272 unsigned old_align;
5273 unsigned old_misalign;
5274 bool old_known = get_ptr_info_alignment (pi, &old_align, &old_misalign);
5276 if (old_known
5277 && old_align >= alignments[i].align)
5279 if (dump_file)
5280 fprintf (dump_file, " But the alignment was already %u.\n",
5281 old_align);
5282 continue;
5284 set_ptr_info_alignment (pi, alignments[i].align, alignments[i].misalign);
5288 /* IPCP transformation phase doing propagation of aggregate values. */
5290 unsigned int
5291 ipcp_transform_function (struct cgraph_node *node)
5293 vec<ipa_param_descriptor> descriptors = vNULL;
5294 struct func_body_info fbi;
5295 struct ipa_agg_replacement_value *aggval;
5296 int param_count;
5297 bool cfg_changed = false, something_changed = false;
5299 gcc_checking_assert (cfun);
5300 gcc_checking_assert (current_function_decl);
5302 if (dump_file)
5303 fprintf (dump_file, "Modification phase of node %s/%i\n",
5304 node->name (), node->order);
5306 ipcp_update_alignments (node);
5307 aggval = ipa_get_agg_replacements_for_node (node);
5308 if (!aggval)
5309 return 0;
5310 param_count = count_formal_params (node->decl);
5311 if (param_count == 0)
5312 return 0;
5313 adjust_agg_replacement_values (node, aggval);
5314 if (dump_file)
5315 ipa_dump_agg_replacement_values (dump_file, aggval);
5317 fbi.node = node;
5318 fbi.info = NULL;
5319 fbi.bb_infos = vNULL;
5320 fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun));
5321 fbi.param_count = param_count;
5322 fbi.aa_walked = 0;
5324 descriptors.safe_grow_cleared (param_count);
5325 ipa_populate_param_decls (node, descriptors);
5326 calculate_dominance_info (CDI_DOMINATORS);
5327 ipcp_modif_dom_walker (&fbi, descriptors, aggval, &something_changed,
5328 &cfg_changed).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
5330 int i;
5331 struct ipa_bb_info *bi;
5332 FOR_EACH_VEC_ELT (fbi.bb_infos, i, bi)
5333 free_ipa_bb_info (bi);
5334 fbi.bb_infos.release ();
5335 free_dominance_info (CDI_DOMINATORS);
5336 (*ipcp_transformations)[node->uid].agg_values = NULL;
5337 (*ipcp_transformations)[node->uid].alignments = NULL;
5338 descriptors.release ();
5340 if (!something_changed)
5341 return 0;
5342 else if (cfg_changed)
5343 return TODO_update_ssa_only_virtuals | TODO_cleanup_cfg;
5344 else
5345 return TODO_update_ssa_only_virtuals;