]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ipa-prop.c
re PR rtl-optimization/61215 (ICE in gen_add2_insn, at optabs.c:4718 when building...
[thirdparty/gcc.git] / gcc / ipa-prop.c
CommitLineData
518dc859 1/* Interprocedural analyses.
23a5b65a 2 Copyright (C) 2005-2014 Free Software Foundation, Inc.
518dc859
RL
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
9dcd6f09 8Software Foundation; either version 3, or (at your option) any later
518dc859
RL
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
9dcd6f09
NC
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
518dc859
RL
19
20#include "config.h"
21#include "system.h"
22#include "coretypes.h"
23#include "tree.h"
2fb9a547
AM
24#include "basic-block.h"
25#include "tree-ssa-alias.h"
26#include "internal-fn.h"
27#include "gimple-fold.h"
28#include "tree-eh.h"
29#include "gimple-expr.h"
30#include "is-a.h"
18f429e2 31#include "gimple.h"
d8a2d370
DN
32#include "expr.h"
33#include "stor-layout.h"
34#include "print-tree.h"
45b0be94 35#include "gimplify.h"
5be5c238 36#include "gimple-iterator.h"
18f429e2 37#include "gimplify-me.h"
5be5c238 38#include "gimple-walk.h"
518dc859 39#include "langhooks.h"
518dc859 40#include "target.h"
518dc859 41#include "ipa-prop.h"
442b4905
AM
42#include "bitmap.h"
43#include "gimple-ssa.h"
44#include "tree-cfg.h"
45#include "tree-phinodes.h"
46#include "ssa-iterators.h"
47#include "tree-into-ssa.h"
48#include "tree-dfa.h"
518dc859 49#include "tree-pass.h"
771578a0 50#include "tree-inline.h"
0f378cb5 51#include "ipa-inline.h"
518dc859 52#include "flags.h"
3e293154 53#include "diagnostic.h"
cf835838 54#include "gimple-pretty-print.h"
fb3f88cc 55#include "lto-streamer.h"
f0efc7aa
DN
56#include "data-streamer.h"
57#include "tree-streamer.h"
dfea20f1 58#include "params.h"
450ad0cd 59#include "ipa-utils.h"
4df65a85
RB
60#include "stringpool.h"
61#include "tree-ssanames.h"
2b5f0895 62#include "dbgcnt.h"
771578a0 63
062c604f
MJ
64/* Intermediate information about a parameter that is only useful during the
65 run of ipa_analyze_node and is not kept afterwards. */
66
67struct param_analysis_info
68{
8b7773a4
MJ
69 bool parm_modified, ref_modified, pt_modified;
70 bitmap parm_visited_statements, pt_visited_statements;
062c604f
MJ
71};
72
771578a0 73/* Vector where the parameter infos are actually stored. */
84562394 74vec<ipa_node_params> ipa_node_params_vector;
2c9561b5 75/* Vector of known aggregate values in cloned nodes. */
9771b263 76vec<ipa_agg_replacement_value_p, va_gc> *ipa_node_agg_replacements;
771578a0 77/* Vector where the parameter infos are actually stored. */
84562394 78vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
771578a0
MJ
79
80/* Holders of ipa cgraph hooks: */
e2c9111c
JH
81static struct cgraph_edge_hook_list *edge_removal_hook_holder;
82static struct cgraph_node_hook_list *node_removal_hook_holder;
83static struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
84static struct cgraph_2node_hook_list *node_duplication_hook_holder;
40982661 85static struct cgraph_node_hook_list *function_insertion_hook_holder;
518dc859 86
4502fe8d
MJ
87/* Description of a reference to an IPA constant. */
88struct ipa_cst_ref_desc
89{
90 /* Edge that corresponds to the statement which took the reference. */
91 struct cgraph_edge *cs;
92 /* Linked list of duplicates created when call graph edges are cloned. */
93 struct ipa_cst_ref_desc *next_duplicate;
94 /* Number of references in IPA structures, IPA_UNDESCRIBED_USE if the value
95 if out of control. */
96 int refcount;
97};
98
99/* Allocation pool for reference descriptions. */
100
101static alloc_pool ipa_refdesc_pool;
102
5fe8e757
MJ
103/* Return true if DECL_FUNCTION_SPECIFIC_OPTIMIZATION of the decl associated
104 with NODE should prevent us from analyzing it for the purposes of IPA-CP. */
105
106static bool
107ipa_func_spec_opts_forbid_analysis_p (struct cgraph_node *node)
108{
67348ccc 109 tree fs_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (node->decl);
5fe8e757
MJ
110 struct cl_optimization *os;
111
112 if (!fs_opts)
113 return false;
114 os = TREE_OPTIMIZATION (fs_opts);
115 return !os->x_optimize || !os->x_flag_ipa_cp;
116}
117
be95e2b9
MJ
118/* Return index of the formal whose tree is PTREE in function which corresponds
119 to INFO. */
120
d044dd17 121static int
84562394 122ipa_get_param_decl_index_1 (vec<ipa_param_descriptor> descriptors, tree ptree)
518dc859
RL
123{
124 int i, count;
125
9771b263 126 count = descriptors.length ();
518dc859 127 for (i = 0; i < count; i++)
9771b263 128 if (descriptors[i].decl == ptree)
518dc859
RL
129 return i;
130
131 return -1;
132}
133
d044dd17
MJ
134/* Return index of the formal whose tree is PTREE in function which corresponds
135 to INFO. */
136
137int
138ipa_get_param_decl_index (struct ipa_node_params *info, tree ptree)
139{
140 return ipa_get_param_decl_index_1 (info->descriptors, ptree);
141}
142
143/* Populate the param_decl field in parameter DESCRIPTORS that correspond to
144 NODE. */
be95e2b9 145
f8e2a1ed
MJ
146static void
147ipa_populate_param_decls (struct cgraph_node *node,
84562394 148 vec<ipa_param_descriptor> &descriptors)
518dc859
RL
149{
150 tree fndecl;
151 tree fnargs;
152 tree parm;
153 int param_num;
3e293154 154
67348ccc 155 fndecl = node->decl;
0e8853ee 156 gcc_assert (gimple_has_body_p (fndecl));
518dc859
RL
157 fnargs = DECL_ARGUMENTS (fndecl);
158 param_num = 0;
910ad8de 159 for (parm = fnargs; parm; parm = DECL_CHAIN (parm))
518dc859 160 {
9771b263 161 descriptors[param_num].decl = parm;
0e8853ee 162 descriptors[param_num].move_cost = estimate_move_cost (TREE_TYPE (parm));
518dc859
RL
163 param_num++;
164 }
165}
166
3f84bf08
MJ
167/* Return how many formal parameters FNDECL has. */
168
169static inline int
310bc633 170count_formal_params (tree fndecl)
3f84bf08
MJ
171{
172 tree parm;
173 int count = 0;
0e8853ee 174 gcc_assert (gimple_has_body_p (fndecl));
3f84bf08 175
910ad8de 176 for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
3f84bf08
MJ
177 count++;
178
179 return count;
180}
181
0e8853ee
JH
182/* Return the declaration of Ith formal parameter of the function corresponding
183 to INFO. Note there is no setter function as this array is built just once
184 using ipa_initialize_node_params. */
185
186void
187ipa_dump_param (FILE *file, struct ipa_node_params *info, int i)
188{
189 fprintf (file, "param #%i", i);
190 if (info->descriptors[i].decl)
191 {
192 fprintf (file, " ");
193 print_generic_expr (file, info->descriptors[i].decl, 0);
194 }
195}
196
197/* Initialize the ipa_node_params structure associated with NODE
198 to hold PARAM_COUNT parameters. */
199
200void
201ipa_alloc_node_params (struct cgraph_node *node, int param_count)
202{
203 struct ipa_node_params *info = IPA_NODE_REF (node);
204
205 if (!info->descriptors.exists () && param_count)
206 info->descriptors.safe_grow_cleared (param_count);
207}
208
f8e2a1ed
MJ
209/* Initialize the ipa_node_params structure associated with NODE by counting
210 the function parameters, creating the descriptors and populating their
211 param_decls. */
be95e2b9 212
f8e2a1ed
MJ
213void
214ipa_initialize_node_params (struct cgraph_node *node)
215{
216 struct ipa_node_params *info = IPA_NODE_REF (node);
217
9771b263 218 if (!info->descriptors.exists ())
f8e2a1ed 219 {
67348ccc 220 ipa_alloc_node_params (node, count_formal_params (node->decl));
0e8853ee 221 ipa_populate_param_decls (node, info->descriptors);
f8e2a1ed 222 }
518dc859
RL
223}
224
749aa96d
MJ
225/* Print the jump functions associated with call graph edge CS to file F. */
226
227static void
228ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
229{
230 int i, count;
231
232 count = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
233 for (i = 0; i < count; i++)
234 {
235 struct ipa_jump_func *jump_func;
236 enum jump_func_type type;
237
238 jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
239 type = jump_func->type;
240
241 fprintf (f, " param %d: ", i);
242 if (type == IPA_JF_UNKNOWN)
243 fprintf (f, "UNKNOWN\n");
244 else if (type == IPA_JF_KNOWN_TYPE)
245 {
c7573249
MJ
246 fprintf (f, "KNOWN TYPE: base ");
247 print_generic_expr (f, jump_func->value.known_type.base_type, 0);
248 fprintf (f, ", offset "HOST_WIDE_INT_PRINT_DEC", component ",
249 jump_func->value.known_type.offset);
250 print_generic_expr (f, jump_func->value.known_type.component_type, 0);
251 fprintf (f, "\n");
749aa96d
MJ
252 }
253 else if (type == IPA_JF_CONST)
254 {
4502fe8d 255 tree val = jump_func->value.constant.value;
749aa96d
MJ
256 fprintf (f, "CONST: ");
257 print_generic_expr (f, val, 0);
258 if (TREE_CODE (val) == ADDR_EXPR
259 && TREE_CODE (TREE_OPERAND (val, 0)) == CONST_DECL)
260 {
261 fprintf (f, " -> ");
262 print_generic_expr (f, DECL_INITIAL (TREE_OPERAND (val, 0)),
263 0);
264 }
265 fprintf (f, "\n");
266 }
749aa96d
MJ
267 else if (type == IPA_JF_PASS_THROUGH)
268 {
269 fprintf (f, "PASS THROUGH: ");
8b7773a4 270 fprintf (f, "%d, op %s",
749aa96d 271 jump_func->value.pass_through.formal_id,
5806f481 272 get_tree_code_name(jump_func->value.pass_through.operation));
749aa96d 273 if (jump_func->value.pass_through.operation != NOP_EXPR)
8b7773a4
MJ
274 {
275 fprintf (f, " ");
276 print_generic_expr (f,
277 jump_func->value.pass_through.operand, 0);
278 }
279 if (jump_func->value.pass_through.agg_preserved)
280 fprintf (f, ", agg_preserved");
b8f6e610
MJ
281 if (jump_func->value.pass_through.type_preserved)
282 fprintf (f, ", type_preserved");
3ea6239f 283 fprintf (f, "\n");
749aa96d
MJ
284 }
285 else if (type == IPA_JF_ANCESTOR)
286 {
287 fprintf (f, "ANCESTOR: ");
288 fprintf (f, "%d, offset "HOST_WIDE_INT_PRINT_DEC", ",
289 jump_func->value.ancestor.formal_id,
290 jump_func->value.ancestor.offset);
291 print_generic_expr (f, jump_func->value.ancestor.type, 0);
8b7773a4
MJ
292 if (jump_func->value.ancestor.agg_preserved)
293 fprintf (f, ", agg_preserved");
b8f6e610
MJ
294 if (jump_func->value.ancestor.type_preserved)
295 fprintf (f, ", type_preserved");
3ea6239f 296 fprintf (f, "\n");
749aa96d 297 }
8b7773a4
MJ
298
299 if (jump_func->agg.items)
300 {
301 struct ipa_agg_jf_item *item;
302 int j;
303
304 fprintf (f, " Aggregate passed by %s:\n",
305 jump_func->agg.by_ref ? "reference" : "value");
9771b263 306 FOR_EACH_VEC_SAFE_ELT (jump_func->agg.items, j, item)
8b7773a4
MJ
307 {
308 fprintf (f, " offset: " HOST_WIDE_INT_PRINT_DEC ", ",
309 item->offset);
310 if (TYPE_P (item->value))
311 fprintf (f, "clobber of " HOST_WIDE_INT_PRINT_DEC " bits",
ae7e9ddd 312 tree_to_uhwi (TYPE_SIZE (item->value)));
8b7773a4
MJ
313 else
314 {
315 fprintf (f, "cst: ");
316 print_generic_expr (f, item->value, 0);
317 }
318 fprintf (f, "\n");
319 }
320 }
749aa96d
MJ
321 }
322}
323
324
be95e2b9
MJ
325/* Print the jump functions of all arguments on all call graph edges going from
326 NODE to file F. */
327
518dc859 328void
3e293154 329ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
518dc859 330{
3e293154 331 struct cgraph_edge *cs;
518dc859 332
fec39fa6 333 fprintf (f, " Jump functions of caller %s/%i:\n", node->name (),
67348ccc 334 node->order);
3e293154
MJ
335 for (cs = node->callees; cs; cs = cs->next_callee)
336 {
337 if (!ipa_edge_args_info_available_for_edge_p (cs))
338 continue;
339
749aa96d 340 fprintf (f, " callsite %s/%i -> %s/%i : \n",
fec39fa6
TS
341 xstrdup (node->name ()), node->order,
342 xstrdup (cs->callee->name ()),
67348ccc 343 cs->callee->order);
749aa96d
MJ
344 ipa_print_node_jump_functions_for_edge (f, cs);
345 }
518dc859 346
9de04252 347 for (cs = node->indirect_calls; cs; cs = cs->next_callee)
749aa96d 348 {
9de04252 349 struct cgraph_indirect_call_info *ii;
749aa96d
MJ
350 if (!ipa_edge_args_info_available_for_edge_p (cs))
351 continue;
3e293154 352
9de04252
MJ
353 ii = cs->indirect_info;
354 if (ii->agg_contents)
c13bc3d9 355 fprintf (f, " indirect %s callsite, calling param %i, "
9de04252 356 "offset " HOST_WIDE_INT_PRINT_DEC ", %s",
c13bc3d9 357 ii->member_ptr ? "member ptr" : "aggregate",
9de04252
MJ
358 ii->param_index, ii->offset,
359 ii->by_ref ? "by reference" : "by_value");
360 else
85942f45
JH
361 fprintf (f, " indirect %s callsite, calling param %i, "
362 "offset " HOST_WIDE_INT_PRINT_DEC,
363 ii->polymorphic ? "polymorphic" : "simple", ii->param_index,
364 ii->offset);
9de04252 365
749aa96d
MJ
366 if (cs->call_stmt)
367 {
9de04252 368 fprintf (f, ", for stmt ");
749aa96d 369 print_gimple_stmt (f, cs->call_stmt, 0, TDF_SLIM);
3e293154 370 }
749aa96d 371 else
9de04252 372 fprintf (f, "\n");
749aa96d 373 ipa_print_node_jump_functions_for_edge (f, cs);
3e293154
MJ
374 }
375}
376
377/* Print ipa_jump_func data structures of all nodes in the call graph to F. */
be95e2b9 378
3e293154
MJ
379void
380ipa_print_all_jump_functions (FILE *f)
381{
382 struct cgraph_node *node;
383
ca30a539 384 fprintf (f, "\nJump functions:\n");
65c70e6b 385 FOR_EACH_FUNCTION (node)
3e293154
MJ
386 {
387 ipa_print_node_jump_functions (f, node);
388 }
389}
390
7b872d9e
MJ
391/* Set JFUNC to be a known type jump function. */
392
393static void
394ipa_set_jf_known_type (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
395 tree base_type, tree component_type)
396{
06d65050
JH
397 gcc_assert (TREE_CODE (component_type) == RECORD_TYPE
398 && TYPE_BINFO (component_type));
0a2550e7
JH
399 if (!flag_devirtualize)
400 return;
401 gcc_assert (BINFO_VTABLE (TYPE_BINFO (component_type)));
7b872d9e
MJ
402 jfunc->type = IPA_JF_KNOWN_TYPE;
403 jfunc->value.known_type.offset = offset,
404 jfunc->value.known_type.base_type = base_type;
405 jfunc->value.known_type.component_type = component_type;
68377e53 406 gcc_assert (component_type);
7b872d9e
MJ
407}
408
b8f6e610
MJ
409/* Set JFUNC to be a copy of another jmp (to be used by jump function
410 combination code). The two functions will share their rdesc. */
411
412static void
413ipa_set_jf_cst_copy (struct ipa_jump_func *dst,
414 struct ipa_jump_func *src)
415
416{
417 gcc_checking_assert (src->type == IPA_JF_CONST);
418 dst->type = IPA_JF_CONST;
419 dst->value.constant = src->value.constant;
420}
421
7b872d9e
MJ
422/* Set JFUNC to be a constant jmp function. */
423
424static void
4502fe8d
MJ
425ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
426 struct cgraph_edge *cs)
7b872d9e 427{
5368224f
DC
428 constant = unshare_expr (constant);
429 if (constant && EXPR_P (constant))
430 SET_EXPR_LOCATION (constant, UNKNOWN_LOCATION);
7b872d9e 431 jfunc->type = IPA_JF_CONST;
4502fe8d
MJ
432 jfunc->value.constant.value = unshare_expr_without_location (constant);
433
434 if (TREE_CODE (constant) == ADDR_EXPR
435 && TREE_CODE (TREE_OPERAND (constant, 0)) == FUNCTION_DECL)
436 {
437 struct ipa_cst_ref_desc *rdesc;
438 if (!ipa_refdesc_pool)
439 ipa_refdesc_pool = create_alloc_pool ("IPA-PROP ref descriptions",
440 sizeof (struct ipa_cst_ref_desc), 32);
441
442 rdesc = (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
443 rdesc->cs = cs;
444 rdesc->next_duplicate = NULL;
445 rdesc->refcount = 1;
446 jfunc->value.constant.rdesc = rdesc;
447 }
448 else
449 jfunc->value.constant.rdesc = NULL;
7b872d9e
MJ
450}
451
452/* Set JFUNC to be a simple pass-through jump function. */
453static void
8b7773a4 454ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
b8f6e610 455 bool agg_preserved, bool type_preserved)
7b872d9e
MJ
456{
457 jfunc->type = IPA_JF_PASS_THROUGH;
458 jfunc->value.pass_through.operand = NULL_TREE;
459 jfunc->value.pass_through.formal_id = formal_id;
460 jfunc->value.pass_through.operation = NOP_EXPR;
8b7773a4 461 jfunc->value.pass_through.agg_preserved = agg_preserved;
b8f6e610 462 jfunc->value.pass_through.type_preserved = type_preserved;
7b872d9e
MJ
463}
464
465/* Set JFUNC to be an arithmetic pass through jump function. */
466
467static void
468ipa_set_jf_arith_pass_through (struct ipa_jump_func *jfunc, int formal_id,
469 tree operand, enum tree_code operation)
470{
471 jfunc->type = IPA_JF_PASS_THROUGH;
d1f98542 472 jfunc->value.pass_through.operand = unshare_expr_without_location (operand);
7b872d9e
MJ
473 jfunc->value.pass_through.formal_id = formal_id;
474 jfunc->value.pass_through.operation = operation;
8b7773a4 475 jfunc->value.pass_through.agg_preserved = false;
b8f6e610 476 jfunc->value.pass_through.type_preserved = false;
7b872d9e
MJ
477}
478
479/* Set JFUNC to be an ancestor jump function. */
480
481static void
482ipa_set_ancestor_jf (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
b8f6e610
MJ
483 tree type, int formal_id, bool agg_preserved,
484 bool type_preserved)
7b872d9e 485{
0a2550e7
JH
486 if (!flag_devirtualize)
487 type_preserved = false;
488 gcc_assert (!type_preserved
489 || (TREE_CODE (type) == RECORD_TYPE
490 && TYPE_BINFO (type)
491 && BINFO_VTABLE (TYPE_BINFO (type))));
7b872d9e
MJ
492 jfunc->type = IPA_JF_ANCESTOR;
493 jfunc->value.ancestor.formal_id = formal_id;
494 jfunc->value.ancestor.offset = offset;
0a2550e7 495 jfunc->value.ancestor.type = type_preserved ? type : NULL;
8b7773a4 496 jfunc->value.ancestor.agg_preserved = agg_preserved;
b8f6e610 497 jfunc->value.ancestor.type_preserved = type_preserved;
7b872d9e
MJ
498}
499
e248d83f
MJ
500/* Extract the acual BINFO being described by JFUNC which must be a known type
501 jump function. */
502
503tree
504ipa_binfo_from_known_type_jfunc (struct ipa_jump_func *jfunc)
505{
506 tree base_binfo = TYPE_BINFO (jfunc->value.known_type.base_type);
507 if (!base_binfo)
508 return NULL_TREE;
509 return get_binfo_at_offset (base_binfo,
510 jfunc->value.known_type.offset,
511 jfunc->value.known_type.component_type);
512}
513
f65cf2b7
MJ
514/* Structure to be passed in between detect_type_change and
515 check_stmt_for_type_change. */
516
517struct type_change_info
518{
290ebcb7
MJ
519 /* Offset into the object where there is the virtual method pointer we are
520 looking for. */
521 HOST_WIDE_INT offset;
522 /* The declaration or SSA_NAME pointer of the base that we are checking for
523 type change. */
524 tree object;
525 /* If we actually can tell the type that the object has changed to, it is
526 stored in this field. Otherwise it remains NULL_TREE. */
527 tree known_current_type;
f65cf2b7
MJ
528 /* Set to true if dynamic type change has been detected. */
529 bool type_maybe_changed;
290ebcb7
MJ
530 /* Set to true if multiple types have been encountered. known_current_type
531 must be disregarded in that case. */
532 bool multiple_types_encountered;
f65cf2b7
MJ
533};
534
535/* Return true if STMT can modify a virtual method table pointer.
536
537 This function makes special assumptions about both constructors and
538 destructors which are all the functions that are allowed to alter the VMT
539 pointers. It assumes that destructors begin with assignment into all VMT
540 pointers and that constructors essentially look in the following way:
541
542 1) The very first thing they do is that they call constructors of ancestor
543 sub-objects that have them.
544
545 2) Then VMT pointers of this and all its ancestors is set to new values
546 corresponding to the type corresponding to the constructor.
547
548 3) Only afterwards, other stuff such as constructor of member sub-objects
549 and the code written by the user is run. Only this may include calling
550 virtual functions, directly or indirectly.
551
552 There is no way to call a constructor of an ancestor sub-object in any
553 other way.
554
555 This means that we do not have to care whether constructors get the correct
556 type information because they will always change it (in fact, if we define
557 the type to be given by the VMT pointer, it is undefined).
558
559 The most important fact to derive from the above is that if, for some
560 statement in the section 3, we try to detect whether the dynamic type has
561 changed, we can safely ignore all calls as we examine the function body
562 backwards until we reach statements in section 2 because these calls cannot
563 be ancestor constructors or destructors (if the input is not bogus) and so
564 do not change the dynamic type (this holds true only for automatically
565 allocated objects but at the moment we devirtualize only these). We then
566 must detect that statements in section 2 change the dynamic type and can try
567 to derive the new type. That is enough and we can stop, we will never see
568 the calls into constructors of sub-objects in this code. Therefore we can
569 safely ignore all call statements that we traverse.
570 */
571
572static bool
573stmt_may_be_vtbl_ptr_store (gimple stmt)
574{
575 if (is_gimple_call (stmt))
576 return false;
993df21e 577 /* TODO: Skip clobbers, doing so triggers problem in PR60306. */
f65cf2b7
MJ
578 else if (is_gimple_assign (stmt))
579 {
580 tree lhs = gimple_assign_lhs (stmt);
581
0004f992
MJ
582 if (!AGGREGATE_TYPE_P (TREE_TYPE (lhs)))
583 {
584 if (flag_strict_aliasing
585 && !POINTER_TYPE_P (TREE_TYPE (lhs)))
586 return false;
587
588 if (TREE_CODE (lhs) == COMPONENT_REF
589 && !DECL_VIRTUAL_P (TREE_OPERAND (lhs, 1)))
f65cf2b7 590 return false;
0004f992
MJ
591 /* In the future we might want to use get_base_ref_and_offset to find
592 if there is a field corresponding to the offset and if so, proceed
593 almost like if it was a component ref. */
594 }
f65cf2b7
MJ
595 }
596 return true;
597}
598
290ebcb7
MJ
599/* If STMT can be proved to be an assignment to the virtual method table
600 pointer of ANALYZED_OBJ and the type associated with the new table
601 identified, return the type. Otherwise return NULL_TREE. */
602
603static tree
604extr_type_from_vtbl_ptr_store (gimple stmt, struct type_change_info *tci)
605{
606 HOST_WIDE_INT offset, size, max_size;
390675c8 607 tree lhs, rhs, base, binfo;
290ebcb7
MJ
608
609 if (!gimple_assign_single_p (stmt))
610 return NULL_TREE;
611
612 lhs = gimple_assign_lhs (stmt);
613 rhs = gimple_assign_rhs1 (stmt);
614 if (TREE_CODE (lhs) != COMPONENT_REF
390675c8 615 || !DECL_VIRTUAL_P (TREE_OPERAND (lhs, 1)))
290ebcb7
MJ
616 return NULL_TREE;
617
618 base = get_ref_base_and_extent (lhs, &offset, &size, &max_size);
619 if (offset != tci->offset
620 || size != POINTER_SIZE
621 || max_size != POINTER_SIZE)
622 return NULL_TREE;
623 if (TREE_CODE (base) == MEM_REF)
624 {
625 if (TREE_CODE (tci->object) != MEM_REF
626 || TREE_OPERAND (tci->object, 0) != TREE_OPERAND (base, 0)
627 || !tree_int_cst_equal (TREE_OPERAND (tci->object, 1),
628 TREE_OPERAND (base, 1)))
629 return NULL_TREE;
630 }
631 else if (tci->object != base)
632 return NULL_TREE;
633
390675c8
JH
634 binfo = vtable_pointer_value_to_binfo (rhs);
635
636 /* FIXME: vtable_pointer_value_to_binfo may return BINFO of a
637 base of outer type. In this case we would need to either
638 work on binfos or translate it back to outer type and offset.
639 KNOWN_TYPE jump functions are not ready for that, yet. */
640 if (!binfo || TYPE_BINFO (BINFO_TYPE (binfo)) != binfo)
641 return NULL;
642
643 return BINFO_TYPE (binfo);
290ebcb7
MJ
644}
645
61502ca8 646/* Callback of walk_aliased_vdefs and a helper function for
f65cf2b7
MJ
647 detect_type_change to check whether a particular statement may modify
648 the virtual table pointer, and if possible also determine the new type of
649 the (sub-)object. It stores its result into DATA, which points to a
650 type_change_info structure. */
651
652static bool
653check_stmt_for_type_change (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
654{
655 gimple stmt = SSA_NAME_DEF_STMT (vdef);
656 struct type_change_info *tci = (struct type_change_info *) data;
657
658 if (stmt_may_be_vtbl_ptr_store (stmt))
659 {
290ebcb7
MJ
660 tree type;
661 type = extr_type_from_vtbl_ptr_store (stmt, tci);
662 if (tci->type_maybe_changed
663 && type != tci->known_current_type)
664 tci->multiple_types_encountered = true;
665 tci->known_current_type = type;
f65cf2b7
MJ
666 tci->type_maybe_changed = true;
667 return true;
668 }
669 else
670 return false;
671}
672
290ebcb7
MJ
673
674
06d65050
JH
675/* Detect whether the dynamic type of ARG of COMP_TYPE has changed (before
676 callsite CALL) by looking for assignments to its virtual table pointer. If
677 it is, return true and fill in the jump function JFUNC with relevant type
678 information or set it to unknown. ARG is the object itself (not a pointer
679 to it, unless dereferenced). BASE is the base of the memory access as
680 returned by get_ref_base_and_extent, as is the offset. */
f65cf2b7
MJ
681
682static bool
06d65050
JH
683detect_type_change (tree arg, tree base, tree comp_type, gimple call,
684 struct ipa_jump_func *jfunc, HOST_WIDE_INT offset)
f65cf2b7
MJ
685{
686 struct type_change_info tci;
687 ao_ref ao;
688
689 gcc_checking_assert (DECL_P (arg)
690 || TREE_CODE (arg) == MEM_REF
691 || handled_component_p (arg));
692 /* Const calls cannot call virtual methods through VMT and so type changes do
693 not matter. */
06d65050
JH
694 if (!flag_devirtualize || !gimple_vuse (call)
695 /* Be sure expected_type is polymorphic. */
696 || !comp_type
697 || TREE_CODE (comp_type) != RECORD_TYPE
698 || !TYPE_BINFO (comp_type)
699 || !BINFO_VTABLE (TYPE_BINFO (comp_type)))
0a2550e7 700 return true;
f65cf2b7 701
4bf2a588
JH
702 /* C++ methods are not allowed to change THIS pointer unless they
703 are constructors or destructors. */
704 if (TREE_CODE (base) == MEM_REF
705 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME
706 && SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (base, 0))
707 && TREE_CODE (SSA_NAME_VAR (TREE_OPERAND (base, 0))) == PARM_DECL
708 && TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE
709 && !DECL_CXX_CONSTRUCTOR_P (current_function_decl)
710 && !DECL_CXX_DESTRUCTOR_P (current_function_decl)
711 && (SSA_NAME_VAR (TREE_OPERAND (base, 0))
712 == DECL_ARGUMENTS (current_function_decl)))
713 return false;
714
dd887943 715 ao_ref_init (&ao, arg);
f65cf2b7
MJ
716 ao.base = base;
717 ao.offset = offset;
718 ao.size = POINTER_SIZE;
719 ao.max_size = ao.size;
f65cf2b7 720
290ebcb7
MJ
721 tci.offset = offset;
722 tci.object = get_base_address (arg);
723 tci.known_current_type = NULL_TREE;
724 tci.type_maybe_changed = false;
725 tci.multiple_types_encountered = false;
726
f65cf2b7
MJ
727 walk_aliased_vdefs (&ao, gimple_vuse (call), check_stmt_for_type_change,
728 &tci, NULL);
729 if (!tci.type_maybe_changed)
730 return false;
731
290ebcb7
MJ
732 if (!tci.known_current_type
733 || tci.multiple_types_encountered
734 || offset != 0)
735 jfunc->type = IPA_JF_UNKNOWN;
736 else
7b872d9e 737 ipa_set_jf_known_type (jfunc, 0, tci.known_current_type, comp_type);
290ebcb7 738
f65cf2b7
MJ
739 return true;
740}
741
742/* Like detect_type_change but ARG is supposed to be a non-dereferenced pointer
743 SSA name (its dereference will become the base and the offset is assumed to
744 be zero). */
745
746static bool
06d65050
JH
747detect_type_change_ssa (tree arg, tree comp_type,
748 gimple call, struct ipa_jump_func *jfunc)
f65cf2b7
MJ
749{
750 gcc_checking_assert (TREE_CODE (arg) == SSA_NAME);
05842ff5 751 if (!flag_devirtualize
06d65050 752 || !POINTER_TYPE_P (TREE_TYPE (arg)))
f65cf2b7
MJ
753 return false;
754
755 arg = build2 (MEM_REF, ptr_type_node, arg,
290ebcb7 756 build_int_cst (ptr_type_node, 0));
f65cf2b7 757
06d65050 758 return detect_type_change (arg, arg, comp_type, call, jfunc, 0);
f65cf2b7
MJ
759}
760
fdb0e1b4
MJ
761/* Callback of walk_aliased_vdefs. Flags that it has been invoked to the
762 boolean variable pointed to by DATA. */
763
764static bool
765mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
766 void *data)
767{
768 bool *b = (bool *) data;
769 *b = true;
770 return true;
771}
772
688010ba 773/* Return true if a load from a formal parameter PARM_LOAD is known to retrieve
8b7773a4
MJ
774 a value known not to be modified in this function before reaching the
775 statement STMT. PARM_AINFO is a pointer to a structure containing temporary
776 information about the parameter. */
fdb0e1b4
MJ
777
778static bool
8b7773a4
MJ
779parm_preserved_before_stmt_p (struct param_analysis_info *parm_ainfo,
780 gimple stmt, tree parm_load)
fdb0e1b4
MJ
781{
782 bool modified = false;
8b7773a4 783 bitmap *visited_stmts;
fdb0e1b4
MJ
784 ao_ref refd;
785
8b7773a4
MJ
786 if (parm_ainfo && parm_ainfo->parm_modified)
787 return false;
fdb0e1b4
MJ
788
789 gcc_checking_assert (gimple_vuse (stmt) != NULL_TREE);
8b7773a4
MJ
790 ao_ref_init (&refd, parm_load);
791 /* We can cache visited statements only when parm_ainfo is available and when
792 we are looking at a naked load of the whole parameter. */
793 if (!parm_ainfo || TREE_CODE (parm_load) != PARM_DECL)
794 visited_stmts = NULL;
795 else
796 visited_stmts = &parm_ainfo->parm_visited_statements;
797 walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified, &modified,
798 visited_stmts);
799 if (parm_ainfo && modified)
800 parm_ainfo->parm_modified = true;
801 return !modified;
fdb0e1b4
MJ
802}
803
804/* If STMT is an assignment that loads a value from an parameter declaration,
805 return the index of the parameter in ipa_node_params which has not been
806 modified. Otherwise return -1. */
807
808static int
84562394 809load_from_unmodified_param (vec<ipa_param_descriptor> descriptors,
fdb0e1b4
MJ
810 struct param_analysis_info *parms_ainfo,
811 gimple stmt)
812{
813 int index;
814 tree op1;
815
816 if (!gimple_assign_single_p (stmt))
817 return -1;
818
819 op1 = gimple_assign_rhs1 (stmt);
820 if (TREE_CODE (op1) != PARM_DECL)
821 return -1;
822
d044dd17 823 index = ipa_get_param_decl_index_1 (descriptors, op1);
fdb0e1b4 824 if (index < 0
8b7773a4
MJ
825 || !parm_preserved_before_stmt_p (parms_ainfo ? &parms_ainfo[index]
826 : NULL, stmt, op1))
fdb0e1b4
MJ
827 return -1;
828
829 return index;
830}
f65cf2b7 831
8b7773a4
MJ
832/* Return true if memory reference REF loads data that are known to be
833 unmodified in this function before reaching statement STMT. PARM_AINFO, if
834 non-NULL, is a pointer to a structure containing temporary information about
835 PARM. */
836
837static bool
838parm_ref_data_preserved_p (struct param_analysis_info *parm_ainfo,
839 gimple stmt, tree ref)
840{
841 bool modified = false;
842 ao_ref refd;
843
844 gcc_checking_assert (gimple_vuse (stmt));
845 if (parm_ainfo && parm_ainfo->ref_modified)
846 return false;
847
848 ao_ref_init (&refd, ref);
849 walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified, &modified,
850 NULL);
851 if (parm_ainfo && modified)
852 parm_ainfo->ref_modified = true;
853 return !modified;
854}
855
856/* Return true if the data pointed to by PARM is known to be unmodified in this
857 function before reaching call statement CALL into which it is passed.
858 PARM_AINFO is a pointer to a structure containing temporary information
859 about PARM. */
860
861static bool
862parm_ref_data_pass_through_p (struct param_analysis_info *parm_ainfo,
863 gimple call, tree parm)
864{
865 bool modified = false;
866 ao_ref refd;
867
868 /* It's unnecessary to calculate anything about memory contnets for a const
869 function because it is not goin to use it. But do not cache the result
870 either. Also, no such calculations for non-pointers. */
871 if (!gimple_vuse (call)
872 || !POINTER_TYPE_P (TREE_TYPE (parm)))
873 return false;
874
875 if (parm_ainfo->pt_modified)
876 return false;
877
878 ao_ref_init_from_ptr_and_size (&refd, parm, NULL_TREE);
879 walk_aliased_vdefs (&refd, gimple_vuse (call), mark_modified, &modified,
880 parm_ainfo ? &parm_ainfo->pt_visited_statements : NULL);
881 if (modified)
882 parm_ainfo->pt_modified = true;
883 return !modified;
884}
885
886/* Return true if we can prove that OP is a memory reference loading unmodified
887 data from an aggregate passed as a parameter and if the aggregate is passed
888 by reference, that the alias type of the load corresponds to the type of the
889 formal parameter (so that we can rely on this type for TBAA in callers).
890 INFO and PARMS_AINFO describe parameters of the current function (but the
891 latter can be NULL), STMT is the load statement. If function returns true,
892 *INDEX_P, *OFFSET_P and *BY_REF is filled with the parameter index, offset
893 within the aggregate and whether it is a load from a value passed by
894 reference respectively. */
895
896static bool
84562394 897ipa_load_from_parm_agg_1 (vec<ipa_param_descriptor> descriptors,
8b7773a4
MJ
898 struct param_analysis_info *parms_ainfo, gimple stmt,
899 tree op, int *index_p, HOST_WIDE_INT *offset_p,
3ff2ca23 900 HOST_WIDE_INT *size_p, bool *by_ref_p)
8b7773a4
MJ
901{
902 int index;
903 HOST_WIDE_INT size, max_size;
904 tree base = get_ref_base_and_extent (op, offset_p, &size, &max_size);
905
906 if (max_size == -1 || max_size != size || *offset_p < 0)
907 return false;
908
909 if (DECL_P (base))
910 {
d044dd17 911 int index = ipa_get_param_decl_index_1 (descriptors, base);
8b7773a4
MJ
912 if (index >= 0
913 && parm_preserved_before_stmt_p (parms_ainfo ? &parms_ainfo[index]
914 : NULL, stmt, op))
915 {
916 *index_p = index;
917 *by_ref_p = false;
3ff2ca23
JJ
918 if (size_p)
919 *size_p = size;
8b7773a4
MJ
920 return true;
921 }
922 return false;
923 }
924
925 if (TREE_CODE (base) != MEM_REF
926 || TREE_CODE (TREE_OPERAND (base, 0)) != SSA_NAME
927 || !integer_zerop (TREE_OPERAND (base, 1)))
928 return false;
929
930 if (SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (base, 0)))
931 {
932 tree parm = SSA_NAME_VAR (TREE_OPERAND (base, 0));
d044dd17 933 index = ipa_get_param_decl_index_1 (descriptors, parm);
8b7773a4
MJ
934 }
935 else
936 {
937 /* This branch catches situations where a pointer parameter is not a
938 gimple register, for example:
939
940 void hip7(S*) (struct S * p)
941 {
942 void (*<T2e4>) (struct S *) D.1867;
943 struct S * p.1;
944
945 <bb 2>:
946 p.1_1 = p;
947 D.1867_2 = p.1_1->f;
948 D.1867_2 ();
949 gdp = &p;
950 */
951
952 gimple def = SSA_NAME_DEF_STMT (TREE_OPERAND (base, 0));
d044dd17 953 index = load_from_unmodified_param (descriptors, parms_ainfo, def);
8b7773a4
MJ
954 }
955
956 if (index >= 0
957 && parm_ref_data_preserved_p (parms_ainfo ? &parms_ainfo[index] : NULL,
958 stmt, op))
959 {
960 *index_p = index;
961 *by_ref_p = true;
3ff2ca23
JJ
962 if (size_p)
963 *size_p = size;
8b7773a4
MJ
964 return true;
965 }
966 return false;
967}
968
969/* Just like the previous function, just without the param_analysis_info
970 pointer, for users outside of this file. */
971
972bool
973ipa_load_from_parm_agg (struct ipa_node_params *info, gimple stmt,
974 tree op, int *index_p, HOST_WIDE_INT *offset_p,
975 bool *by_ref_p)
976{
d044dd17 977 return ipa_load_from_parm_agg_1 (info->descriptors, NULL, stmt, op, index_p,
3ff2ca23 978 offset_p, NULL, by_ref_p);
8b7773a4
MJ
979}
980
b258210c 981/* Given that an actual argument is an SSA_NAME (given in NAME) and is a result
fdb0e1b4
MJ
982 of an assignment statement STMT, try to determine whether we are actually
983 handling any of the following cases and construct an appropriate jump
984 function into JFUNC if so:
985
986 1) The passed value is loaded from a formal parameter which is not a gimple
987 register (most probably because it is addressable, the value has to be
988 scalar) and we can guarantee the value has not changed. This case can
989 therefore be described by a simple pass-through jump function. For example:
990
991 foo (int a)
992 {
993 int a.0;
994
995 a.0_2 = a;
996 bar (a.0_2);
997
998 2) The passed value can be described by a simple arithmetic pass-through
999 jump function. E.g.
1000
1001 foo (int a)
1002 {
1003 int D.2064;
1004
1005 D.2064_4 = a.1(D) + 4;
1006 bar (D.2064_4);
1007
1008 This case can also occur in combination of the previous one, e.g.:
1009
1010 foo (int a, int z)
1011 {
1012 int a.0;
1013 int D.2064;
1014
1015 a.0_3 = a;
1016 D.2064_4 = a.0_3 + 4;
1017 foo (D.2064_4);
1018
1019 3) The passed value is an address of an object within another one (which
1020 also passed by reference). Such situations are described by an ancestor
1021 jump function and describe situations such as:
1022
1023 B::foo() (struct B * const this)
1024 {
1025 struct A * D.1845;
1026
1027 D.1845_2 = &this_1(D)->D.1748;
1028 A::bar (D.1845_2);
1029
1030 INFO is the structure describing individual parameters access different
1031 stages of IPA optimizations. PARMS_AINFO contains the information that is
1032 only needed for intraprocedural analysis. */
685b0d13
MJ
1033
1034static void
b258210c 1035compute_complex_assign_jump_func (struct ipa_node_params *info,
fdb0e1b4 1036 struct param_analysis_info *parms_ainfo,
b258210c 1037 struct ipa_jump_func *jfunc,
06d65050
JH
1038 gimple call, gimple stmt, tree name,
1039 tree param_type)
685b0d13
MJ
1040{
1041 HOST_WIDE_INT offset, size, max_size;
fdb0e1b4 1042 tree op1, tc_ssa, base, ssa;
685b0d13 1043 int index;
685b0d13 1044
685b0d13 1045 op1 = gimple_assign_rhs1 (stmt);
685b0d13 1046
fdb0e1b4 1047 if (TREE_CODE (op1) == SSA_NAME)
685b0d13 1048 {
fdb0e1b4
MJ
1049 if (SSA_NAME_IS_DEFAULT_DEF (op1))
1050 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (op1));
1051 else
d044dd17 1052 index = load_from_unmodified_param (info->descriptors, parms_ainfo,
fdb0e1b4
MJ
1053 SSA_NAME_DEF_STMT (op1));
1054 tc_ssa = op1;
1055 }
1056 else
1057 {
d044dd17 1058 index = load_from_unmodified_param (info->descriptors, parms_ainfo, stmt);
fdb0e1b4
MJ
1059 tc_ssa = gimple_assign_lhs (stmt);
1060 }
1061
1062 if (index >= 0)
1063 {
1064 tree op2 = gimple_assign_rhs2 (stmt);
685b0d13 1065
b258210c 1066 if (op2)
685b0d13 1067 {
b258210c
MJ
1068 if (!is_gimple_ip_invariant (op2)
1069 || (TREE_CODE_CLASS (gimple_expr_code (stmt)) != tcc_comparison
1070 && !useless_type_conversion_p (TREE_TYPE (name),
1071 TREE_TYPE (op1))))
1072 return;
1073
7b872d9e
MJ
1074 ipa_set_jf_arith_pass_through (jfunc, index, op2,
1075 gimple_assign_rhs_code (stmt));
685b0d13 1076 }
b8f6e610 1077 else if (gimple_assign_single_p (stmt))
8b7773a4
MJ
1078 {
1079 bool agg_p = parm_ref_data_pass_through_p (&parms_ainfo[index],
1080 call, tc_ssa);
06d65050
JH
1081 bool type_p = false;
1082
1083 if (param_type && POINTER_TYPE_P (param_type))
1084 type_p = !detect_type_change_ssa (tc_ssa, TREE_TYPE (param_type),
1085 call, jfunc);
b8f6e610
MJ
1086 if (type_p || jfunc->type == IPA_JF_UNKNOWN)
1087 ipa_set_jf_simple_pass_through (jfunc, index, agg_p, type_p);
8b7773a4 1088 }
685b0d13
MJ
1089 return;
1090 }
1091
1092 if (TREE_CODE (op1) != ADDR_EXPR)
1093 return;
1094 op1 = TREE_OPERAND (op1, 0);
f65cf2b7 1095 if (TREE_CODE (TREE_TYPE (op1)) != RECORD_TYPE)
b258210c 1096 return;
32aa622c
MJ
1097 base = get_ref_base_and_extent (op1, &offset, &size, &max_size);
1098 if (TREE_CODE (base) != MEM_REF
1a15bfdc
RG
1099 /* If this is a varying address, punt. */
1100 || max_size == -1
1101 || max_size != size)
685b0d13 1102 return;
807e902e 1103 offset += mem_ref_offset (base).to_short_addr () * BITS_PER_UNIT;
f65cf2b7
MJ
1104 ssa = TREE_OPERAND (base, 0);
1105 if (TREE_CODE (ssa) != SSA_NAME
1106 || !SSA_NAME_IS_DEFAULT_DEF (ssa)
280fedf0 1107 || offset < 0)
685b0d13
MJ
1108 return;
1109
b8f6e610 1110 /* Dynamic types are changed in constructors and destructors. */
f65cf2b7 1111 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (ssa));
06d65050 1112 if (index >= 0 && param_type && POINTER_TYPE_P (param_type))
b8f6e610 1113 {
06d65050
JH
1114 bool type_p = !detect_type_change (op1, base, TREE_TYPE (param_type),
1115 call, jfunc, offset);
b8f6e610 1116 if (type_p || jfunc->type == IPA_JF_UNKNOWN)
0a2550e7
JH
1117 ipa_set_ancestor_jf (jfunc, offset,
1118 type_p ? TREE_TYPE (param_type) : NULL, index,
b8f6e610
MJ
1119 parm_ref_data_pass_through_p (&parms_ainfo[index],
1120 call, ssa), type_p);
1121 }
685b0d13
MJ
1122}
1123
40591473
MJ
1124/* Extract the base, offset and MEM_REF expression from a statement ASSIGN if
1125 it looks like:
1126
1127 iftmp.1_3 = &obj_2(D)->D.1762;
1128
1129 The base of the MEM_REF must be a default definition SSA NAME of a
1130 parameter. Return NULL_TREE if it looks otherwise. If case of success, the
1131 whole MEM_REF expression is returned and the offset calculated from any
1132 handled components and the MEM_REF itself is stored into *OFFSET. The whole
1133 RHS stripped off the ADDR_EXPR is stored into *OBJ_P. */
1134
1135static tree
1136get_ancestor_addr_info (gimple assign, tree *obj_p, HOST_WIDE_INT *offset)
1137{
1138 HOST_WIDE_INT size, max_size;
1139 tree expr, parm, obj;
1140
1141 if (!gimple_assign_single_p (assign))
1142 return NULL_TREE;
1143 expr = gimple_assign_rhs1 (assign);
1144
1145 if (TREE_CODE (expr) != ADDR_EXPR)
1146 return NULL_TREE;
1147 expr = TREE_OPERAND (expr, 0);
1148 obj = expr;
1149 expr = get_ref_base_and_extent (expr, offset, &size, &max_size);
1150
1151 if (TREE_CODE (expr) != MEM_REF
1152 /* If this is a varying address, punt. */
1153 || max_size == -1
1154 || max_size != size
1155 || *offset < 0)
1156 return NULL_TREE;
1157 parm = TREE_OPERAND (expr, 0);
1158 if (TREE_CODE (parm) != SSA_NAME
1159 || !SSA_NAME_IS_DEFAULT_DEF (parm)
1160 || TREE_CODE (SSA_NAME_VAR (parm)) != PARM_DECL)
1161 return NULL_TREE;
1162
807e902e 1163 *offset += mem_ref_offset (expr).to_short_addr () * BITS_PER_UNIT;
40591473
MJ
1164 *obj_p = obj;
1165 return expr;
1166}
1167
685b0d13 1168
b258210c
MJ
1169/* Given that an actual argument is an SSA_NAME that is a result of a phi
1170 statement PHI, try to find out whether NAME is in fact a
1171 multiple-inheritance typecast from a descendant into an ancestor of a formal
1172 parameter and thus can be described by an ancestor jump function and if so,
1173 write the appropriate function into JFUNC.
1174
1175 Essentially we want to match the following pattern:
1176
1177 if (obj_2(D) != 0B)
1178 goto <bb 3>;
1179 else
1180 goto <bb 4>;
1181
1182 <bb 3>:
1183 iftmp.1_3 = &obj_2(D)->D.1762;
1184
1185 <bb 4>:
1186 # iftmp.1_1 = PHI <iftmp.1_3(3), 0B(2)>
1187 D.1879_6 = middleman_1 (iftmp.1_1, i_5(D));
1188 return D.1879_6; */
1189
1190static void
1191compute_complex_ancestor_jump_func (struct ipa_node_params *info,
8b7773a4 1192 struct param_analysis_info *parms_ainfo,
b258210c 1193 struct ipa_jump_func *jfunc,
06d65050 1194 gimple call, gimple phi, tree param_type)
b258210c 1195{
40591473 1196 HOST_WIDE_INT offset;
b258210c
MJ
1197 gimple assign, cond;
1198 basic_block phi_bb, assign_bb, cond_bb;
f65cf2b7 1199 tree tmp, parm, expr, obj;
b258210c
MJ
1200 int index, i;
1201
54e348cb 1202 if (gimple_phi_num_args (phi) != 2)
b258210c
MJ
1203 return;
1204
54e348cb
MJ
1205 if (integer_zerop (PHI_ARG_DEF (phi, 1)))
1206 tmp = PHI_ARG_DEF (phi, 0);
1207 else if (integer_zerop (PHI_ARG_DEF (phi, 0)))
1208 tmp = PHI_ARG_DEF (phi, 1);
1209 else
1210 return;
b258210c
MJ
1211 if (TREE_CODE (tmp) != SSA_NAME
1212 || SSA_NAME_IS_DEFAULT_DEF (tmp)
1213 || !POINTER_TYPE_P (TREE_TYPE (tmp))
1214 || TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) != RECORD_TYPE)
1215 return;
1216
1217 assign = SSA_NAME_DEF_STMT (tmp);
1218 assign_bb = gimple_bb (assign);
40591473 1219 if (!single_pred_p (assign_bb))
b258210c 1220 return;
40591473
MJ
1221 expr = get_ancestor_addr_info (assign, &obj, &offset);
1222 if (!expr)
b258210c
MJ
1223 return;
1224 parm = TREE_OPERAND (expr, 0);
b258210c 1225 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (parm));
20afe640
EB
1226 if (index < 0)
1227 return;
b258210c
MJ
1228
1229 cond_bb = single_pred (assign_bb);
1230 cond = last_stmt (cond_bb);
69610617
SB
1231 if (!cond
1232 || gimple_code (cond) != GIMPLE_COND
b258210c
MJ
1233 || gimple_cond_code (cond) != NE_EXPR
1234 || gimple_cond_lhs (cond) != parm
1235 || !integer_zerop (gimple_cond_rhs (cond)))
1236 return;
1237
b258210c
MJ
1238 phi_bb = gimple_bb (phi);
1239 for (i = 0; i < 2; i++)
1240 {
1241 basic_block pred = EDGE_PRED (phi_bb, i)->src;
1242 if (pred != assign_bb && pred != cond_bb)
1243 return;
1244 }
1245
06d65050
JH
1246 bool type_p = false;
1247 if (param_type && POINTER_TYPE_P (param_type))
1248 type_p = !detect_type_change (obj, expr, TREE_TYPE (param_type),
1249 call, jfunc, offset);
b8f6e610 1250 if (type_p || jfunc->type == IPA_JF_UNKNOWN)
0a2550e7 1251 ipa_set_ancestor_jf (jfunc, offset, type_p ? TREE_TYPE (param_type) : NULL, index,
8b7773a4 1252 parm_ref_data_pass_through_p (&parms_ainfo[index],
b8f6e610 1253 call, parm), type_p);
b258210c
MJ
1254}
1255
61502ca8 1256/* Given OP which is passed as an actual argument to a called function,
b258210c 1257 determine if it is possible to construct a KNOWN_TYPE jump function for it
06d65050
JH
1258 and if so, create one and store it to JFUNC.
1259 EXPECTED_TYPE represents a type the argument should be in */
b258210c
MJ
1260
1261static void
f65cf2b7 1262compute_known_type_jump_func (tree op, struct ipa_jump_func *jfunc,
06d65050 1263 gimple call, tree expected_type)
b258210c 1264{
32aa622c 1265 HOST_WIDE_INT offset, size, max_size;
c7573249 1266 tree base;
b258210c 1267
05842ff5
MJ
1268 if (!flag_devirtualize
1269 || TREE_CODE (op) != ADDR_EXPR
06d65050
JH
1270 || TREE_CODE (TREE_TYPE (TREE_TYPE (op))) != RECORD_TYPE
1271 /* Be sure expected_type is polymorphic. */
1272 || !expected_type
1273 || TREE_CODE (expected_type) != RECORD_TYPE
1274 || !TYPE_BINFO (expected_type)
1275 || !BINFO_VTABLE (TYPE_BINFO (expected_type)))
b258210c
MJ
1276 return;
1277
1278 op = TREE_OPERAND (op, 0);
32aa622c
MJ
1279 base = get_ref_base_and_extent (op, &offset, &size, &max_size);
1280 if (!DECL_P (base)
1281 || max_size == -1
1282 || max_size != size
1283 || TREE_CODE (TREE_TYPE (base)) != RECORD_TYPE
1284 || is_global_var (base))
1285 return;
1286
06d65050 1287 if (detect_type_change (op, base, expected_type, call, jfunc, offset))
f65cf2b7
MJ
1288 return;
1289
06d65050
JH
1290 ipa_set_jf_known_type (jfunc, offset, TREE_TYPE (base),
1291 expected_type);
b258210c
MJ
1292}
1293
be95e2b9
MJ
1294/* Inspect the given TYPE and return true iff it has the same structure (the
1295 same number of fields of the same types) as a C++ member pointer. If
1296 METHOD_PTR and DELTA are non-NULL, store the trees representing the
1297 corresponding fields there. */
1298
3e293154
MJ
1299static bool
1300type_like_member_ptr_p (tree type, tree *method_ptr, tree *delta)
1301{
1302 tree fld;
1303
1304 if (TREE_CODE (type) != RECORD_TYPE)
1305 return false;
1306
1307 fld = TYPE_FIELDS (type);
1308 if (!fld || !POINTER_TYPE_P (TREE_TYPE (fld))
8b7773a4 1309 || TREE_CODE (TREE_TYPE (TREE_TYPE (fld))) != METHOD_TYPE
cc269bb6 1310 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
3e293154
MJ
1311 return false;
1312
1313 if (method_ptr)
1314 *method_ptr = fld;
1315
910ad8de 1316 fld = DECL_CHAIN (fld);
8b7773a4 1317 if (!fld || INTEGRAL_TYPE_P (fld)
cc269bb6 1318 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
3e293154
MJ
1319 return false;
1320 if (delta)
1321 *delta = fld;
1322
910ad8de 1323 if (DECL_CHAIN (fld))
3e293154
MJ
1324 return false;
1325
1326 return true;
1327}
1328
61502ca8 1329/* If RHS is an SSA_NAME and it is defined by a simple copy assign statement,
8b7773a4
MJ
1330 return the rhs of its defining statement. Otherwise return RHS as it
1331 is. */
7ec49257
MJ
1332
1333static inline tree
1334get_ssa_def_if_simple_copy (tree rhs)
1335{
1336 while (TREE_CODE (rhs) == SSA_NAME && !SSA_NAME_IS_DEFAULT_DEF (rhs))
1337 {
1338 gimple def_stmt = SSA_NAME_DEF_STMT (rhs);
1339
1340 if (gimple_assign_single_p (def_stmt))
1341 rhs = gimple_assign_rhs1 (def_stmt);
9961eb45
MJ
1342 else
1343 break;
7ec49257
MJ
1344 }
1345 return rhs;
1346}
1347
8b7773a4
MJ
1348/* Simple linked list, describing known contents of an aggregate beforere
1349 call. */
1350
1351struct ipa_known_agg_contents_list
1352{
1353 /* Offset and size of the described part of the aggregate. */
1354 HOST_WIDE_INT offset, size;
1355 /* Known constant value or NULL if the contents is known to be unknown. */
1356 tree constant;
1357 /* Pointer to the next structure in the list. */
1358 struct ipa_known_agg_contents_list *next;
1359};
3e293154 1360
8b7773a4
MJ
1361/* Traverse statements from CALL backwards, scanning whether an aggregate given
1362 in ARG is filled in with constant values. ARG can either be an aggregate
85942f45
JH
1363 expression or a pointer to an aggregate. ARG_TYPE is the type of the aggregate.
1364 JFUNC is the jump function into which the constants are subsequently stored. */
be95e2b9 1365
3e293154 1366static void
85942f45 1367determine_known_aggregate_parts (gimple call, tree arg, tree arg_type,
8b7773a4 1368 struct ipa_jump_func *jfunc)
3e293154 1369{
8b7773a4
MJ
1370 struct ipa_known_agg_contents_list *list = NULL;
1371 int item_count = 0, const_count = 0;
1372 HOST_WIDE_INT arg_offset, arg_size;
726a989a 1373 gimple_stmt_iterator gsi;
8b7773a4
MJ
1374 tree arg_base;
1375 bool check_ref, by_ref;
1376 ao_ref r;
3e293154 1377
8b7773a4
MJ
1378 /* The function operates in three stages. First, we prepare check_ref, r,
1379 arg_base and arg_offset based on what is actually passed as an actual
1380 argument. */
3e293154 1381
85942f45 1382 if (POINTER_TYPE_P (arg_type))
8b7773a4
MJ
1383 {
1384 by_ref = true;
1385 if (TREE_CODE (arg) == SSA_NAME)
1386 {
1387 tree type_size;
85942f45 1388 if (!tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (arg_type))))
8b7773a4
MJ
1389 return;
1390 check_ref = true;
1391 arg_base = arg;
1392 arg_offset = 0;
85942f45 1393 type_size = TYPE_SIZE (TREE_TYPE (arg_type));
ae7e9ddd 1394 arg_size = tree_to_uhwi (type_size);
8b7773a4
MJ
1395 ao_ref_init_from_ptr_and_size (&r, arg_base, NULL_TREE);
1396 }
1397 else if (TREE_CODE (arg) == ADDR_EXPR)
1398 {
1399 HOST_WIDE_INT arg_max_size;
1400
1401 arg = TREE_OPERAND (arg, 0);
1402 arg_base = get_ref_base_and_extent (arg, &arg_offset, &arg_size,
1403 &arg_max_size);
1404 if (arg_max_size == -1
1405 || arg_max_size != arg_size
1406 || arg_offset < 0)
1407 return;
1408 if (DECL_P (arg_base))
1409 {
1410 tree size;
1411 check_ref = false;
1412 size = build_int_cst (integer_type_node, arg_size);
1413 ao_ref_init_from_ptr_and_size (&r, arg_base, size);
1414 }
1415 else
1416 return;
1417 }
1418 else
1419 return;
1420 }
1421 else
1422 {
1423 HOST_WIDE_INT arg_max_size;
1424
1425 gcc_checking_assert (AGGREGATE_TYPE_P (TREE_TYPE (arg)));
1426
1427 by_ref = false;
1428 check_ref = false;
1429 arg_base = get_ref_base_and_extent (arg, &arg_offset, &arg_size,
1430 &arg_max_size);
1431 if (arg_max_size == -1
1432 || arg_max_size != arg_size
1433 || arg_offset < 0)
1434 return;
1435
1436 ao_ref_init (&r, arg);
1437 }
1438
1439 /* Second stage walks back the BB, looks at individual statements and as long
1440 as it is confident of how the statements affect contents of the
1441 aggregates, it builds a sorted linked list of ipa_agg_jf_list structures
1442 describing it. */
1443 gsi = gsi_for_stmt (call);
726a989a
RB
1444 gsi_prev (&gsi);
1445 for (; !gsi_end_p (gsi); gsi_prev (&gsi))
3e293154 1446 {
8b7773a4 1447 struct ipa_known_agg_contents_list *n, **p;
726a989a 1448 gimple stmt = gsi_stmt (gsi);
8b7773a4
MJ
1449 HOST_WIDE_INT lhs_offset, lhs_size, lhs_max_size;
1450 tree lhs, rhs, lhs_base;
1451 bool partial_overlap;
3e293154 1452
8b7773a4 1453 if (!stmt_may_clobber_ref_p_1 (stmt, &r))
8aa29647 1454 continue;
8b75fc9b 1455 if (!gimple_assign_single_p (stmt))
8b7773a4 1456 break;
3e293154 1457
726a989a
RB
1458 lhs = gimple_assign_lhs (stmt);
1459 rhs = gimple_assign_rhs1 (stmt);
0c6b087c 1460 if (!is_gimple_reg_type (TREE_TYPE (rhs))
7d2fb524
MJ
1461 || TREE_CODE (lhs) == BIT_FIELD_REF
1462 || contains_bitfld_component_ref_p (lhs))
8b7773a4 1463 break;
3e293154 1464
8b7773a4
MJ
1465 lhs_base = get_ref_base_and_extent (lhs, &lhs_offset, &lhs_size,
1466 &lhs_max_size);
1467 if (lhs_max_size == -1
1468 || lhs_max_size != lhs_size
1469 || (lhs_offset < arg_offset
1470 && lhs_offset + lhs_size > arg_offset)
1471 || (lhs_offset < arg_offset + arg_size
1472 && lhs_offset + lhs_size > arg_offset + arg_size))
1473 break;
3e293154 1474
8b7773a4 1475 if (check_ref)
518dc859 1476 {
8b7773a4
MJ
1477 if (TREE_CODE (lhs_base) != MEM_REF
1478 || TREE_OPERAND (lhs_base, 0) != arg_base
1479 || !integer_zerop (TREE_OPERAND (lhs_base, 1)))
1480 break;
3e293154 1481 }
8b7773a4 1482 else if (lhs_base != arg_base)
774b8a55
MJ
1483 {
1484 if (DECL_P (lhs_base))
1485 continue;
1486 else
1487 break;
1488 }
3e293154 1489
8b7773a4
MJ
1490 if (lhs_offset + lhs_size < arg_offset
1491 || lhs_offset >= (arg_offset + arg_size))
1492 continue;
1493
1494 partial_overlap = false;
1495 p = &list;
1496 while (*p && (*p)->offset < lhs_offset)
3e293154 1497 {
8b7773a4 1498 if ((*p)->offset + (*p)->size > lhs_offset)
3e293154 1499 {
8b7773a4
MJ
1500 partial_overlap = true;
1501 break;
3e293154 1502 }
8b7773a4
MJ
1503 p = &(*p)->next;
1504 }
1505 if (partial_overlap)
1506 break;
1507 if (*p && (*p)->offset < lhs_offset + lhs_size)
1508 {
1509 if ((*p)->offset == lhs_offset && (*p)->size == lhs_size)
1510 /* We already know this value is subsequently overwritten with
1511 something else. */
1512 continue;
3e293154 1513 else
8b7773a4
MJ
1514 /* Otherwise this is a partial overlap which we cannot
1515 represent. */
1516 break;
3e293154 1517 }
3e293154 1518
8b7773a4
MJ
1519 rhs = get_ssa_def_if_simple_copy (rhs);
1520 n = XALLOCA (struct ipa_known_agg_contents_list);
1521 n->size = lhs_size;
1522 n->offset = lhs_offset;
1523 if (is_gimple_ip_invariant (rhs))
1524 {
1525 n->constant = rhs;
1526 const_count++;
1527 }
1528 else
1529 n->constant = NULL_TREE;
1530 n->next = *p;
1531 *p = n;
3e293154 1532
8b7773a4 1533 item_count++;
dfea20f1
MJ
1534 if (const_count == PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS)
1535 || item_count == 2 * PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS))
8b7773a4
MJ
1536 break;
1537 }
be95e2b9 1538
8b7773a4
MJ
1539 /* Third stage just goes over the list and creates an appropriate vector of
1540 ipa_agg_jf_item structures out of it, of sourse only if there are
1541 any known constants to begin with. */
3e293154 1542
8b7773a4 1543 if (const_count)
3e293154 1544 {
8b7773a4 1545 jfunc->agg.by_ref = by_ref;
9771b263 1546 vec_alloc (jfunc->agg.items, const_count);
8b7773a4
MJ
1547 while (list)
1548 {
1549 if (list->constant)
1550 {
f32682ca
DN
1551 struct ipa_agg_jf_item item;
1552 item.offset = list->offset - arg_offset;
7d2fb524 1553 gcc_assert ((item.offset % BITS_PER_UNIT) == 0);
d1f98542 1554 item.value = unshare_expr_without_location (list->constant);
9771b263 1555 jfunc->agg.items->quick_push (item);
8b7773a4
MJ
1556 }
1557 list = list->next;
1558 }
3e293154
MJ
1559 }
1560}
1561
06d65050
JH
1562static tree
1563ipa_get_callee_param_type (struct cgraph_edge *e, int i)
1564{
1565 int n;
1566 tree type = (e->callee
67348ccc 1567 ? TREE_TYPE (e->callee->decl)
06d65050
JH
1568 : gimple_call_fntype (e->call_stmt));
1569 tree t = TYPE_ARG_TYPES (type);
1570
1571 for (n = 0; n < i; n++)
1572 {
1573 if (!t)
1574 break;
1575 t = TREE_CHAIN (t);
1576 }
1577 if (t)
1578 return TREE_VALUE (t);
1579 if (!e->callee)
1580 return NULL;
67348ccc 1581 t = DECL_ARGUMENTS (e->callee->decl);
06d65050
JH
1582 for (n = 0; n < i; n++)
1583 {
1584 if (!t)
1585 return NULL;
1586 t = TREE_CHAIN (t);
1587 }
1588 if (t)
1589 return TREE_TYPE (t);
1590 return NULL;
1591}
1592
3e293154
MJ
1593/* Compute jump function for all arguments of callsite CS and insert the
1594 information in the jump_functions array in the ipa_edge_args corresponding
1595 to this callsite. */
be95e2b9 1596
749aa96d 1597static void
c419671c 1598ipa_compute_jump_functions_for_edge (struct param_analysis_info *parms_ainfo,
062c604f 1599 struct cgraph_edge *cs)
3e293154
MJ
1600{
1601 struct ipa_node_params *info = IPA_NODE_REF (cs->caller);
606d9a09
MJ
1602 struct ipa_edge_args *args = IPA_EDGE_REF (cs);
1603 gimple call = cs->call_stmt;
8b7773a4 1604 int n, arg_num = gimple_call_num_args (call);
3e293154 1605
606d9a09 1606 if (arg_num == 0 || args->jump_functions)
3e293154 1607 return;
9771b263 1608 vec_safe_grow_cleared (args->jump_functions, arg_num);
3e293154 1609
96e24d49
JJ
1610 if (gimple_call_internal_p (call))
1611 return;
5fe8e757
MJ
1612 if (ipa_func_spec_opts_forbid_analysis_p (cs->caller))
1613 return;
1614
8b7773a4
MJ
1615 for (n = 0; n < arg_num; n++)
1616 {
1617 struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, n);
1618 tree arg = gimple_call_arg (call, n);
06d65050 1619 tree param_type = ipa_get_callee_param_type (cs, n);
3e293154 1620
8b7773a4 1621 if (is_gimple_ip_invariant (arg))
4502fe8d 1622 ipa_set_jf_constant (jfunc, arg, cs);
8b7773a4
MJ
1623 else if (!is_gimple_reg_type (TREE_TYPE (arg))
1624 && TREE_CODE (arg) == PARM_DECL)
1625 {
1626 int index = ipa_get_param_decl_index (info, arg);
1627
1628 gcc_assert (index >=0);
1629 /* Aggregate passed by value, check for pass-through, otherwise we
1630 will attempt to fill in aggregate contents later in this
1631 for cycle. */
1632 if (parm_preserved_before_stmt_p (&parms_ainfo[index], call, arg))
1633 {
b8f6e610 1634 ipa_set_jf_simple_pass_through (jfunc, index, false, false);
8b7773a4
MJ
1635 continue;
1636 }
1637 }
1638 else if (TREE_CODE (arg) == SSA_NAME)
1639 {
1640 if (SSA_NAME_IS_DEFAULT_DEF (arg))
1641 {
1642 int index = ipa_get_param_decl_index (info, SSA_NAME_VAR (arg));
b8f6e610 1643 if (index >= 0)
8b7773a4 1644 {
b8f6e610 1645 bool agg_p, type_p;
8b7773a4
MJ
1646 agg_p = parm_ref_data_pass_through_p (&parms_ainfo[index],
1647 call, arg);
06d65050
JH
1648 if (param_type && POINTER_TYPE_P (param_type))
1649 type_p = !detect_type_change_ssa (arg, TREE_TYPE (param_type),
1650 call, jfunc);
1651 else
1652 type_p = false;
b8f6e610 1653 if (type_p || jfunc->type == IPA_JF_UNKNOWN)
06d65050
JH
1654 ipa_set_jf_simple_pass_through (jfunc, index, agg_p,
1655 type_p);
8b7773a4
MJ
1656 }
1657 }
1658 else
1659 {
1660 gimple stmt = SSA_NAME_DEF_STMT (arg);
1661 if (is_gimple_assign (stmt))
1662 compute_complex_assign_jump_func (info, parms_ainfo, jfunc,
06d65050 1663 call, stmt, arg, param_type);
8b7773a4
MJ
1664 else if (gimple_code (stmt) == GIMPLE_PHI)
1665 compute_complex_ancestor_jump_func (info, parms_ainfo, jfunc,
06d65050 1666 call, stmt, param_type);
8b7773a4
MJ
1667 }
1668 }
1669 else
06d65050
JH
1670 compute_known_type_jump_func (arg, jfunc, call,
1671 param_type
1672 && POINTER_TYPE_P (param_type)
1673 ? TREE_TYPE (param_type)
1674 : NULL);
3e293154 1675
85942f45
JH
1676 /* If ARG is pointer, we can not use its type to determine the type of aggregate
1677 passed (because type conversions are ignored in gimple). Usually we can
1678 safely get type from function declaration, but in case of K&R prototypes or
1679 variadic functions we can try our luck with type of the pointer passed.
1680 TODO: Since we look for actual initialization of the memory object, we may better
1681 work out the type based on the memory stores we find. */
1682 if (!param_type)
1683 param_type = TREE_TYPE (arg);
1684
8b7773a4
MJ
1685 if ((jfunc->type != IPA_JF_PASS_THROUGH
1686 || !ipa_get_jf_pass_through_agg_preserved (jfunc))
1687 && (jfunc->type != IPA_JF_ANCESTOR
1688 || !ipa_get_jf_ancestor_agg_preserved (jfunc))
1689 && (AGGREGATE_TYPE_P (TREE_TYPE (arg))
85942f45
JH
1690 || POINTER_TYPE_P (param_type)))
1691 determine_known_aggregate_parts (call, arg, param_type, jfunc);
8b7773a4 1692 }
3e293154
MJ
1693}
1694
749aa96d
MJ
1695/* Compute jump functions for all edges - both direct and indirect - outgoing
1696 from NODE. Also count the actual arguments in the process. */
1697
062c604f
MJ
1698static void
1699ipa_compute_jump_functions (struct cgraph_node *node,
c419671c 1700 struct param_analysis_info *parms_ainfo)
749aa96d
MJ
1701{
1702 struct cgraph_edge *cs;
1703
1704 for (cs = node->callees; cs; cs = cs->next_callee)
1705 {
d7da5cc8
MJ
1706 struct cgraph_node *callee = cgraph_function_or_thunk_node (cs->callee,
1707 NULL);
749aa96d
MJ
1708 /* We do not need to bother analyzing calls to unknown
1709 functions unless they may become known during lto/whopr. */
67348ccc 1710 if (!callee->definition && !flag_lto)
749aa96d 1711 continue;
c419671c 1712 ipa_compute_jump_functions_for_edge (parms_ainfo, cs);
749aa96d
MJ
1713 }
1714
1715 for (cs = node->indirect_calls; cs; cs = cs->next_callee)
c419671c 1716 ipa_compute_jump_functions_for_edge (parms_ainfo, cs);
749aa96d
MJ
1717}
1718
8b7773a4
MJ
1719/* If STMT looks like a statement loading a value from a member pointer formal
1720 parameter, return that parameter and store the offset of the field to
1721 *OFFSET_P, if it is non-NULL. Otherwise return NULL (but *OFFSET_P still
1722 might be clobbered). If USE_DELTA, then we look for a use of the delta
1723 field rather than the pfn. */
be95e2b9 1724
3e293154 1725static tree
8b7773a4
MJ
1726ipa_get_stmt_member_ptr_load_param (gimple stmt, bool use_delta,
1727 HOST_WIDE_INT *offset_p)
3e293154 1728{
8b7773a4
MJ
1729 tree rhs, rec, ref_field, ref_offset, fld, ptr_field, delta_field;
1730
1731 if (!gimple_assign_single_p (stmt))
1732 return NULL_TREE;
3e293154 1733
8b7773a4 1734 rhs = gimple_assign_rhs1 (stmt);
ae788515
EB
1735 if (TREE_CODE (rhs) == COMPONENT_REF)
1736 {
1737 ref_field = TREE_OPERAND (rhs, 1);
1738 rhs = TREE_OPERAND (rhs, 0);
1739 }
1740 else
1741 ref_field = NULL_TREE;
d242d063 1742 if (TREE_CODE (rhs) != MEM_REF)
3e293154 1743 return NULL_TREE;
3e293154 1744 rec = TREE_OPERAND (rhs, 0);
d242d063
MJ
1745 if (TREE_CODE (rec) != ADDR_EXPR)
1746 return NULL_TREE;
1747 rec = TREE_OPERAND (rec, 0);
3e293154 1748 if (TREE_CODE (rec) != PARM_DECL
6f7b8b70 1749 || !type_like_member_ptr_p (TREE_TYPE (rec), &ptr_field, &delta_field))
3e293154 1750 return NULL_TREE;
d242d063 1751 ref_offset = TREE_OPERAND (rhs, 1);
ae788515 1752
8b7773a4
MJ
1753 if (use_delta)
1754 fld = delta_field;
1755 else
1756 fld = ptr_field;
1757 if (offset_p)
1758 *offset_p = int_bit_position (fld);
1759
ae788515
EB
1760 if (ref_field)
1761 {
1762 if (integer_nonzerop (ref_offset))
1763 return NULL_TREE;
ae788515
EB
1764 return ref_field == fld ? rec : NULL_TREE;
1765 }
3e293154 1766 else
8b7773a4
MJ
1767 return tree_int_cst_equal (byte_position (fld), ref_offset) ? rec
1768 : NULL_TREE;
3e293154
MJ
1769}
1770
1771/* Returns true iff T is an SSA_NAME defined by a statement. */
be95e2b9 1772
3e293154
MJ
1773static bool
1774ipa_is_ssa_with_stmt_def (tree t)
1775{
1776 if (TREE_CODE (t) == SSA_NAME
1777 && !SSA_NAME_IS_DEFAULT_DEF (t))
1778 return true;
1779 else
1780 return false;
1781}
1782
40591473
MJ
1783/* Find the indirect call graph edge corresponding to STMT and mark it as a
1784 call to a parameter number PARAM_INDEX. NODE is the caller. Return the
1785 indirect call graph edge. */
be95e2b9 1786
40591473
MJ
1787static struct cgraph_edge *
1788ipa_note_param_call (struct cgraph_node *node, int param_index, gimple stmt)
3e293154 1789{
e33c6cd6 1790 struct cgraph_edge *cs;
3e293154 1791
5f902d76 1792 cs = cgraph_edge (node, stmt);
b258210c 1793 cs->indirect_info->param_index = param_index;
8b7773a4 1794 cs->indirect_info->agg_contents = 0;
c13bc3d9 1795 cs->indirect_info->member_ptr = 0;
40591473 1796 return cs;
3e293154
MJ
1797}
1798
e33c6cd6 1799/* Analyze the CALL and examine uses of formal parameters of the caller NODE
c419671c 1800 (described by INFO). PARMS_AINFO is a pointer to a vector containing
062c604f
MJ
1801 intermediate information about each formal parameter. Currently it checks
1802 whether the call calls a pointer that is a formal parameter and if so, the
1803 parameter is marked with the called flag and an indirect call graph edge
1804 describing the call is created. This is very simple for ordinary pointers
1805 represented in SSA but not-so-nice when it comes to member pointers. The
1806 ugly part of this function does nothing more than trying to match the
1807 pattern of such a call. An example of such a pattern is the gimple dump
1808 below, the call is on the last line:
3e293154 1809
ae788515
EB
1810 <bb 2>:
1811 f$__delta_5 = f.__delta;
1812 f$__pfn_24 = f.__pfn;
1813
1814 or
3e293154 1815 <bb 2>:
d242d063
MJ
1816 f$__delta_5 = MEM[(struct *)&f];
1817 f$__pfn_24 = MEM[(struct *)&f + 4B];
8aa29647 1818
ae788515 1819 and a few lines below:
8aa29647
MJ
1820
1821 <bb 5>
3e293154
MJ
1822 D.2496_3 = (int) f$__pfn_24;
1823 D.2497_4 = D.2496_3 & 1;
1824 if (D.2497_4 != 0)
1825 goto <bb 3>;
1826 else
1827 goto <bb 4>;
1828
8aa29647 1829 <bb 6>:
3e293154
MJ
1830 D.2500_7 = (unsigned int) f$__delta_5;
1831 D.2501_8 = &S + D.2500_7;
1832 D.2502_9 = (int (*__vtbl_ptr_type) (void) * *) D.2501_8;
1833 D.2503_10 = *D.2502_9;
1834 D.2504_12 = f$__pfn_24 + -1;
1835 D.2505_13 = (unsigned int) D.2504_12;
1836 D.2506_14 = D.2503_10 + D.2505_13;
1837 D.2507_15 = *D.2506_14;
1838 iftmp.11_16 = (String:: *) D.2507_15;
1839
8aa29647 1840 <bb 7>:
3e293154
MJ
1841 # iftmp.11_1 = PHI <iftmp.11_16(3), f$__pfn_24(2)>
1842 D.2500_19 = (unsigned int) f$__delta_5;
1843 D.2508_20 = &S + D.2500_19;
1844 D.2493_21 = iftmp.11_1 (D.2508_20, 4);
1845
1846 Such patterns are results of simple calls to a member pointer:
1847
1848 int doprinting (int (MyString::* f)(int) const)
1849 {
1850 MyString S ("somestring");
1851
1852 return (S.*f)(4);
1853 }
8b7773a4
MJ
1854
1855 Moreover, the function also looks for called pointers loaded from aggregates
1856 passed by value or reference. */
3e293154
MJ
1857
1858static void
b258210c
MJ
1859ipa_analyze_indirect_call_uses (struct cgraph_node *node,
1860 struct ipa_node_params *info,
c419671c 1861 struct param_analysis_info *parms_ainfo,
b258210c 1862 gimple call, tree target)
3e293154 1863{
726a989a 1864 gimple def;
3e293154 1865 tree n1, n2;
726a989a
RB
1866 gimple d1, d2;
1867 tree rec, rec2, cond;
1868 gimple branch;
3e293154 1869 int index;
3e293154 1870 basic_block bb, virt_bb, join;
8b7773a4
MJ
1871 HOST_WIDE_INT offset;
1872 bool by_ref;
3e293154 1873
3e293154
MJ
1874 if (SSA_NAME_IS_DEFAULT_DEF (target))
1875 {
b258210c 1876 tree var = SSA_NAME_VAR (target);
3e293154
MJ
1877 index = ipa_get_param_decl_index (info, var);
1878 if (index >= 0)
40591473 1879 ipa_note_param_call (node, index, call);
3e293154
MJ
1880 return;
1881 }
1882
8b7773a4
MJ
1883 def = SSA_NAME_DEF_STMT (target);
1884 if (gimple_assign_single_p (def)
d044dd17 1885 && ipa_load_from_parm_agg_1 (info->descriptors, parms_ainfo, def,
8b7773a4 1886 gimple_assign_rhs1 (def), &index, &offset,
3ff2ca23 1887 NULL, &by_ref))
8b7773a4
MJ
1888 {
1889 struct cgraph_edge *cs = ipa_note_param_call (node, index, call);
68377e53
JH
1890 if (cs->indirect_info->offset != offset)
1891 cs->indirect_info->outer_type = NULL;
8b7773a4
MJ
1892 cs->indirect_info->offset = offset;
1893 cs->indirect_info->agg_contents = 1;
1894 cs->indirect_info->by_ref = by_ref;
1895 return;
1896 }
1897
3e293154
MJ
1898 /* Now we need to try to match the complex pattern of calling a member
1899 pointer. */
8b7773a4
MJ
1900 if (gimple_code (def) != GIMPLE_PHI
1901 || gimple_phi_num_args (def) != 2
1902 || !POINTER_TYPE_P (TREE_TYPE (target))
3e293154
MJ
1903 || TREE_CODE (TREE_TYPE (TREE_TYPE (target))) != METHOD_TYPE)
1904 return;
1905
3e293154
MJ
1906 /* First, we need to check whether one of these is a load from a member
1907 pointer that is a parameter to this function. */
1908 n1 = PHI_ARG_DEF (def, 0);
1909 n2 = PHI_ARG_DEF (def, 1);
1fc8feb5 1910 if (!ipa_is_ssa_with_stmt_def (n1) || !ipa_is_ssa_with_stmt_def (n2))
3e293154
MJ
1911 return;
1912 d1 = SSA_NAME_DEF_STMT (n1);
1913 d2 = SSA_NAME_DEF_STMT (n2);
1914
8aa29647 1915 join = gimple_bb (def);
8b7773a4 1916 if ((rec = ipa_get_stmt_member_ptr_load_param (d1, false, &offset)))
3e293154 1917 {
8b7773a4 1918 if (ipa_get_stmt_member_ptr_load_param (d2, false, NULL))
3e293154
MJ
1919 return;
1920
8aa29647 1921 bb = EDGE_PRED (join, 0)->src;
726a989a 1922 virt_bb = gimple_bb (d2);
3e293154 1923 }
8b7773a4 1924 else if ((rec = ipa_get_stmt_member_ptr_load_param (d2, false, &offset)))
3e293154 1925 {
8aa29647 1926 bb = EDGE_PRED (join, 1)->src;
726a989a 1927 virt_bb = gimple_bb (d1);
3e293154
MJ
1928 }
1929 else
1930 return;
1931
1932 /* Second, we need to check that the basic blocks are laid out in the way
1933 corresponding to the pattern. */
1934
3e293154
MJ
1935 if (!single_pred_p (virt_bb) || !single_succ_p (virt_bb)
1936 || single_pred (virt_bb) != bb
1937 || single_succ (virt_bb) != join)
1938 return;
1939
1940 /* Third, let's see that the branching is done depending on the least
1941 significant bit of the pfn. */
1942
1943 branch = last_stmt (bb);
8aa29647 1944 if (!branch || gimple_code (branch) != GIMPLE_COND)
3e293154
MJ
1945 return;
1946
12430896
RG
1947 if ((gimple_cond_code (branch) != NE_EXPR
1948 && gimple_cond_code (branch) != EQ_EXPR)
726a989a 1949 || !integer_zerop (gimple_cond_rhs (branch)))
3e293154 1950 return;
3e293154 1951
726a989a 1952 cond = gimple_cond_lhs (branch);
3e293154
MJ
1953 if (!ipa_is_ssa_with_stmt_def (cond))
1954 return;
1955
726a989a 1956 def = SSA_NAME_DEF_STMT (cond);
8b75fc9b 1957 if (!is_gimple_assign (def)
726a989a
RB
1958 || gimple_assign_rhs_code (def) != BIT_AND_EXPR
1959 || !integer_onep (gimple_assign_rhs2 (def)))
3e293154 1960 return;
726a989a
RB
1961
1962 cond = gimple_assign_rhs1 (def);
3e293154
MJ
1963 if (!ipa_is_ssa_with_stmt_def (cond))
1964 return;
1965
726a989a 1966 def = SSA_NAME_DEF_STMT (cond);
3e293154 1967
8b75fc9b
MJ
1968 if (is_gimple_assign (def)
1969 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
3e293154 1970 {
726a989a 1971 cond = gimple_assign_rhs1 (def);
3e293154
MJ
1972 if (!ipa_is_ssa_with_stmt_def (cond))
1973 return;
726a989a 1974 def = SSA_NAME_DEF_STMT (cond);
3e293154
MJ
1975 }
1976
6f7b8b70
RE
1977 rec2 = ipa_get_stmt_member_ptr_load_param (def,
1978 (TARGET_PTRMEMFUNC_VBIT_LOCATION
8b7773a4
MJ
1979 == ptrmemfunc_vbit_in_delta),
1980 NULL);
3e293154
MJ
1981 if (rec != rec2)
1982 return;
1983
1984 index = ipa_get_param_decl_index (info, rec);
8b7773a4
MJ
1985 if (index >= 0
1986 && parm_preserved_before_stmt_p (&parms_ainfo[index], call, rec))
1987 {
1988 struct cgraph_edge *cs = ipa_note_param_call (node, index, call);
68377e53
JH
1989 if (cs->indirect_info->offset != offset)
1990 cs->indirect_info->outer_type = NULL;
8b7773a4
MJ
1991 cs->indirect_info->offset = offset;
1992 cs->indirect_info->agg_contents = 1;
c13bc3d9 1993 cs->indirect_info->member_ptr = 1;
8b7773a4 1994 }
3e293154
MJ
1995
1996 return;
1997}
1998
b258210c
MJ
1999/* Analyze a CALL to an OBJ_TYPE_REF which is passed in TARGET and if the
2000 object referenced in the expression is a formal parameter of the caller
2001 (described by INFO), create a call note for the statement. */
2002
2003static void
2004ipa_analyze_virtual_call_uses (struct cgraph_node *node,
2005 struct ipa_node_params *info, gimple call,
2006 tree target)
2007{
40591473
MJ
2008 struct cgraph_edge *cs;
2009 struct cgraph_indirect_call_info *ii;
f65cf2b7 2010 struct ipa_jump_func jfunc;
b258210c 2011 tree obj = OBJ_TYPE_REF_OBJECT (target);
b258210c 2012 int index;
40591473 2013 HOST_WIDE_INT anc_offset;
b258210c 2014
05842ff5
MJ
2015 if (!flag_devirtualize)
2016 return;
2017
40591473 2018 if (TREE_CODE (obj) != SSA_NAME)
b258210c
MJ
2019 return;
2020
40591473
MJ
2021 if (SSA_NAME_IS_DEFAULT_DEF (obj))
2022 {
2023 if (TREE_CODE (SSA_NAME_VAR (obj)) != PARM_DECL)
2024 return;
b258210c 2025
40591473
MJ
2026 anc_offset = 0;
2027 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (obj));
2028 gcc_assert (index >= 0);
06d65050
JH
2029 if (detect_type_change_ssa (obj, obj_type_ref_class (target),
2030 call, &jfunc))
40591473
MJ
2031 return;
2032 }
2033 else
2034 {
2035 gimple stmt = SSA_NAME_DEF_STMT (obj);
2036 tree expr;
2037
2038 expr = get_ancestor_addr_info (stmt, &obj, &anc_offset);
2039 if (!expr)
2040 return;
2041 index = ipa_get_param_decl_index (info,
2042 SSA_NAME_VAR (TREE_OPERAND (expr, 0)));
2043 gcc_assert (index >= 0);
06d65050
JH
2044 if (detect_type_change (obj, expr, obj_type_ref_class (target),
2045 call, &jfunc, anc_offset))
40591473
MJ
2046 return;
2047 }
2048
2049 cs = ipa_note_param_call (node, index, call);
2050 ii = cs->indirect_info;
8b7773a4 2051 ii->offset = anc_offset;
ae7e9ddd 2052 ii->otr_token = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target));
c49bdb2e 2053 ii->otr_type = obj_type_ref_class (target);
40591473 2054 ii->polymorphic = 1;
b258210c
MJ
2055}
2056
2057/* Analyze a call statement CALL whether and how it utilizes formal parameters
c419671c 2058 of the caller (described by INFO). PARMS_AINFO is a pointer to a vector
062c604f 2059 containing intermediate information about each formal parameter. */
b258210c
MJ
2060
2061static void
2062ipa_analyze_call_uses (struct cgraph_node *node,
062c604f 2063 struct ipa_node_params *info,
c419671c 2064 struct param_analysis_info *parms_ainfo, gimple call)
b258210c
MJ
2065{
2066 tree target = gimple_call_fn (call);
b786d31f
JH
2067 struct cgraph_edge *cs;
2068
2069 if (!target
2070 || (TREE_CODE (target) != SSA_NAME
2071 && !virtual_method_call_p (target)))
2072 return;
b258210c 2073
b786d31f
JH
2074 /* If we previously turned the call into a direct call, there is
2075 no need to analyze. */
2076 cs = cgraph_edge (node, call);
2077 if (cs && !cs->indirect_unknown_callee)
25583c4f 2078 return;
b258210c 2079 if (TREE_CODE (target) == SSA_NAME)
c419671c 2080 ipa_analyze_indirect_call_uses (node, info, parms_ainfo, call, target);
1d5755ef 2081 else if (virtual_method_call_p (target))
b258210c
MJ
2082 ipa_analyze_virtual_call_uses (node, info, call, target);
2083}
2084
2085
e33c6cd6
MJ
2086/* Analyze the call statement STMT with respect to formal parameters (described
2087 in INFO) of caller given by NODE. Currently it only checks whether formal
c419671c 2088 parameters are called. PARMS_AINFO is a pointer to a vector containing
062c604f 2089 intermediate information about each formal parameter. */
be95e2b9 2090
3e293154 2091static void
e33c6cd6 2092ipa_analyze_stmt_uses (struct cgraph_node *node, struct ipa_node_params *info,
c419671c 2093 struct param_analysis_info *parms_ainfo, gimple stmt)
3e293154 2094{
726a989a 2095 if (is_gimple_call (stmt))
c419671c 2096 ipa_analyze_call_uses (node, info, parms_ainfo, stmt);
062c604f
MJ
2097}
2098
2099/* Callback of walk_stmt_load_store_addr_ops for the visit_load.
2100 If OP is a parameter declaration, mark it as used in the info structure
2101 passed in DATA. */
2102
2103static bool
9f1363cd 2104visit_ref_for_mod_analysis (gimple, tree op, tree, void *data)
062c604f
MJ
2105{
2106 struct ipa_node_params *info = (struct ipa_node_params *) data;
2107
2108 op = get_base_address (op);
2109 if (op
2110 && TREE_CODE (op) == PARM_DECL)
2111 {
2112 int index = ipa_get_param_decl_index (info, op);
2113 gcc_assert (index >= 0);
310bc633 2114 ipa_set_param_used (info, index, true);
062c604f
MJ
2115 }
2116
2117 return false;
3e293154
MJ
2118}
2119
2120/* Scan the function body of NODE and inspect the uses of formal parameters.
2121 Store the findings in various structures of the associated ipa_node_params
c419671c 2122 structure, such as parameter flags, notes etc. PARMS_AINFO is a pointer to a
062c604f 2123 vector containing intermediate information about each formal parameter. */
be95e2b9 2124
062c604f
MJ
2125static void
2126ipa_analyze_params_uses (struct cgraph_node *node,
c419671c 2127 struct param_analysis_info *parms_ainfo)
3e293154 2128{
67348ccc 2129 tree decl = node->decl;
3e293154
MJ
2130 basic_block bb;
2131 struct function *func;
726a989a 2132 gimple_stmt_iterator gsi;
3e293154 2133 struct ipa_node_params *info = IPA_NODE_REF (node);
062c604f 2134 int i;
3e293154 2135
726a989a 2136 if (ipa_get_param_count (info) == 0 || info->uses_analysis_done)
3e293154 2137 return;
3e293154 2138
5fe8e757
MJ
2139 info->uses_analysis_done = 1;
2140 if (ipa_func_spec_opts_forbid_analysis_p (node))
2141 {
2142 for (i = 0; i < ipa_get_param_count (info); i++)
2143 {
2144 ipa_set_param_used (info, i, true);
2145 ipa_set_controlled_uses (info, i, IPA_UNDESCRIBED_USE);
2146 }
2147 return;
2148 }
2149
062c604f
MJ
2150 for (i = 0; i < ipa_get_param_count (info); i++)
2151 {
2152 tree parm = ipa_get_param (info, i);
4502fe8d
MJ
2153 int controlled_uses = 0;
2154
062c604f
MJ
2155 /* For SSA regs see if parameter is used. For non-SSA we compute
2156 the flag during modification analysis. */
4502fe8d
MJ
2157 if (is_gimple_reg (parm))
2158 {
67348ccc 2159 tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl),
4502fe8d
MJ
2160 parm);
2161 if (ddef && !has_zero_uses (ddef))
2162 {
2163 imm_use_iterator imm_iter;
2164 use_operand_p use_p;
2165
2166 ipa_set_param_used (info, i, true);
2167 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, ddef)
2168 if (!is_gimple_call (USE_STMT (use_p)))
2169 {
c6de6665
JJ
2170 if (!is_gimple_debug (USE_STMT (use_p)))
2171 {
2172 controlled_uses = IPA_UNDESCRIBED_USE;
2173 break;
2174 }
4502fe8d
MJ
2175 }
2176 else
2177 controlled_uses++;
2178 }
2179 else
2180 controlled_uses = 0;
2181 }
2182 else
2183 controlled_uses = IPA_UNDESCRIBED_USE;
2184 ipa_set_controlled_uses (info, i, controlled_uses);
062c604f
MJ
2185 }
2186
3e293154
MJ
2187 func = DECL_STRUCT_FUNCTION (decl);
2188 FOR_EACH_BB_FN (bb, func)
2189 {
726a989a 2190 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3e293154 2191 {
726a989a 2192 gimple stmt = gsi_stmt (gsi);
062c604f
MJ
2193
2194 if (is_gimple_debug (stmt))
2195 continue;
2196
c419671c 2197 ipa_analyze_stmt_uses (node, info, parms_ainfo, stmt);
062c604f
MJ
2198 walk_stmt_load_store_addr_ops (stmt, info,
2199 visit_ref_for_mod_analysis,
2200 visit_ref_for_mod_analysis,
2201 visit_ref_for_mod_analysis);
518dc859 2202 }
355a7673 2203 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
062c604f
MJ
2204 walk_stmt_load_store_addr_ops (gsi_stmt (gsi), info,
2205 visit_ref_for_mod_analysis,
2206 visit_ref_for_mod_analysis,
2207 visit_ref_for_mod_analysis);
518dc859 2208 }
3e293154
MJ
2209}
2210
2c9561b5
MJ
2211/* Free stuff in PARMS_AINFO, assume there are PARAM_COUNT parameters. */
2212
2213static void
2214free_parms_ainfo (struct param_analysis_info *parms_ainfo, int param_count)
2215{
2216 int i;
2217
2218 for (i = 0; i < param_count; i++)
2219 {
2220 if (parms_ainfo[i].parm_visited_statements)
2221 BITMAP_FREE (parms_ainfo[i].parm_visited_statements);
2222 if (parms_ainfo[i].pt_visited_statements)
2223 BITMAP_FREE (parms_ainfo[i].pt_visited_statements);
2224 }
2225}
2226
dd5a833e
MS
2227/* Initialize the array describing properties of of formal parameters
2228 of NODE, analyze their uses and compute jump functions associated
2229 with actual arguments of calls from within NODE. */
062c604f
MJ
2230
2231void
2232ipa_analyze_node (struct cgraph_node *node)
2233{
57dbdc5a 2234 struct ipa_node_params *info;
c419671c 2235 struct param_analysis_info *parms_ainfo;
2c9561b5 2236 int param_count;
062c604f 2237
57dbdc5a
MJ
2238 ipa_check_create_node_params ();
2239 ipa_check_create_edge_args ();
2240 info = IPA_NODE_REF (node);
67348ccc 2241 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
062c604f
MJ
2242 ipa_initialize_node_params (node);
2243
2244 param_count = ipa_get_param_count (info);
c419671c
MJ
2245 parms_ainfo = XALLOCAVEC (struct param_analysis_info, param_count);
2246 memset (parms_ainfo, 0, sizeof (struct param_analysis_info) * param_count);
062c604f 2247
c419671c
MJ
2248 ipa_analyze_params_uses (node, parms_ainfo);
2249 ipa_compute_jump_functions (node, parms_ainfo);
062c604f 2250
2c9561b5 2251 free_parms_ainfo (parms_ainfo, param_count);
f65cf2b7 2252 pop_cfun ();
062c604f
MJ
2253}
2254
e248d83f
MJ
2255/* Given a statement CALL which must be a GIMPLE_CALL calling an OBJ_TYPE_REF
2256 attempt a type-based devirtualization. If successful, return the
2257 target function declaration, otherwise return NULL. */
2258
2259tree
2260ipa_intraprocedural_devirtualization (gimple call)
2261{
2262 tree binfo, token, fndecl;
2263 struct ipa_jump_func jfunc;
2264 tree otr = gimple_call_fn (call);
2265
2266 jfunc.type = IPA_JF_UNKNOWN;
2267 compute_known_type_jump_func (OBJ_TYPE_REF_OBJECT (otr), &jfunc,
06d65050 2268 call, obj_type_ref_class (otr));
e248d83f
MJ
2269 if (jfunc.type != IPA_JF_KNOWN_TYPE)
2270 return NULL_TREE;
2271 binfo = ipa_binfo_from_known_type_jfunc (&jfunc);
2272 if (!binfo)
2273 return NULL_TREE;
2274 token = OBJ_TYPE_REF_TOKEN (otr);
ae7e9ddd 2275 fndecl = gimple_get_virt_method_for_binfo (tree_to_uhwi (token),
e248d83f 2276 binfo);
450ad0cd
JH
2277#ifdef ENABLE_CHECKING
2278 if (fndecl)
2279 gcc_assert (possible_polymorphic_call_target_p
2280 (otr, cgraph_get_node (fndecl)));
2281#endif
e248d83f
MJ
2282 return fndecl;
2283}
062c604f 2284
61502ca8 2285/* Update the jump function DST when the call graph edge corresponding to SRC is
b258210c
MJ
2286 is being inlined, knowing that DST is of type ancestor and src of known
2287 type. */
2288
2289static void
2290combine_known_type_and_ancestor_jfs (struct ipa_jump_func *src,
2291 struct ipa_jump_func *dst)
2292{
c7573249
MJ
2293 HOST_WIDE_INT combined_offset;
2294 tree combined_type;
b258210c 2295
b8f6e610
MJ
2296 if (!ipa_get_jf_ancestor_type_preserved (dst))
2297 {
2298 dst->type = IPA_JF_UNKNOWN;
2299 return;
2300 }
2301
7b872d9e
MJ
2302 combined_offset = ipa_get_jf_known_type_offset (src)
2303 + ipa_get_jf_ancestor_offset (dst);
2304 combined_type = ipa_get_jf_ancestor_type (dst);
c7573249 2305
7b872d9e
MJ
2306 ipa_set_jf_known_type (dst, combined_offset,
2307 ipa_get_jf_known_type_base_type (src),
2308 combined_type);
b258210c
MJ
2309}
2310
be95e2b9 2311/* Update the jump functions associated with call graph edge E when the call
3e293154 2312 graph edge CS is being inlined, assuming that E->caller is already (possibly
b258210c 2313 indirectly) inlined into CS->callee and that E has not been inlined. */
be95e2b9 2314
3e293154
MJ
2315static void
2316update_jump_functions_after_inlining (struct cgraph_edge *cs,
2317 struct cgraph_edge *e)
2318{
2319 struct ipa_edge_args *top = IPA_EDGE_REF (cs);
2320 struct ipa_edge_args *args = IPA_EDGE_REF (e);
2321 int count = ipa_get_cs_argument_count (args);
2322 int i;
2323
2324 for (i = 0; i < count; i++)
2325 {
b258210c 2326 struct ipa_jump_func *dst = ipa_get_ith_jump_func (args, i);
3e293154 2327
685b0d13
MJ
2328 if (dst->type == IPA_JF_ANCESTOR)
2329 {
b258210c 2330 struct ipa_jump_func *src;
8b7773a4 2331 int dst_fid = dst->value.ancestor.formal_id;
685b0d13 2332
b258210c
MJ
2333 /* Variable number of arguments can cause havoc if we try to access
2334 one that does not exist in the inlined edge. So make sure we
2335 don't. */
8b7773a4 2336 if (dst_fid >= ipa_get_cs_argument_count (top))
b258210c
MJ
2337 {
2338 dst->type = IPA_JF_UNKNOWN;
2339 continue;
2340 }
2341
8b7773a4
MJ
2342 src = ipa_get_ith_jump_func (top, dst_fid);
2343
2344 if (src->agg.items
2345 && (dst->value.ancestor.agg_preserved || !src->agg.by_ref))
2346 {
2347 struct ipa_agg_jf_item *item;
2348 int j;
2349
2350 /* Currently we do not produce clobber aggregate jump functions,
2351 replace with merging when we do. */
2352 gcc_assert (!dst->agg.items);
2353
9771b263 2354 dst->agg.items = vec_safe_copy (src->agg.items);
8b7773a4 2355 dst->agg.by_ref = src->agg.by_ref;
9771b263 2356 FOR_EACH_VEC_SAFE_ELT (dst->agg.items, j, item)
8b7773a4
MJ
2357 item->offset -= dst->value.ancestor.offset;
2358 }
2359
b258210c
MJ
2360 if (src->type == IPA_JF_KNOWN_TYPE)
2361 combine_known_type_and_ancestor_jfs (src, dst);
b258210c
MJ
2362 else if (src->type == IPA_JF_PASS_THROUGH
2363 && src->value.pass_through.operation == NOP_EXPR)
8b7773a4
MJ
2364 {
2365 dst->value.ancestor.formal_id = src->value.pass_through.formal_id;
2366 dst->value.ancestor.agg_preserved &=
2367 src->value.pass_through.agg_preserved;
b8f6e610
MJ
2368 dst->value.ancestor.type_preserved &=
2369 src->value.pass_through.type_preserved;
8b7773a4 2370 }
b258210c
MJ
2371 else if (src->type == IPA_JF_ANCESTOR)
2372 {
2373 dst->value.ancestor.formal_id = src->value.ancestor.formal_id;
2374 dst->value.ancestor.offset += src->value.ancestor.offset;
8b7773a4
MJ
2375 dst->value.ancestor.agg_preserved &=
2376 src->value.ancestor.agg_preserved;
b8f6e610
MJ
2377 dst->value.ancestor.type_preserved &=
2378 src->value.ancestor.type_preserved;
b258210c
MJ
2379 }
2380 else
2381 dst->type = IPA_JF_UNKNOWN;
2382 }
2383 else if (dst->type == IPA_JF_PASS_THROUGH)
3e293154 2384 {
b258210c
MJ
2385 struct ipa_jump_func *src;
2386 /* We must check range due to calls with variable number of arguments
2387 and we cannot combine jump functions with operations. */
2388 if (dst->value.pass_through.operation == NOP_EXPR
2389 && (dst->value.pass_through.formal_id
2390 < ipa_get_cs_argument_count (top)))
2391 {
8b7773a4
MJ
2392 int dst_fid = dst->value.pass_through.formal_id;
2393 src = ipa_get_ith_jump_func (top, dst_fid);
b8f6e610 2394 bool dst_agg_p = ipa_get_jf_pass_through_agg_preserved (dst);
8b7773a4 2395
b8f6e610
MJ
2396 switch (src->type)
2397 {
2398 case IPA_JF_UNKNOWN:
2399 dst->type = IPA_JF_UNKNOWN;
2400 break;
2401 case IPA_JF_KNOWN_TYPE:
2ace77c2
JH
2402 if (ipa_get_jf_pass_through_type_preserved (dst))
2403 ipa_set_jf_known_type (dst,
2404 ipa_get_jf_known_type_offset (src),
2405 ipa_get_jf_known_type_base_type (src),
0a2550e7 2406 ipa_get_jf_known_type_component_type (src));
2ace77c2
JH
2407 else
2408 dst->type = IPA_JF_UNKNOWN;
b8f6e610
MJ
2409 break;
2410 case IPA_JF_CONST:
2411 ipa_set_jf_cst_copy (dst, src);
2412 break;
2413
2414 case IPA_JF_PASS_THROUGH:
2415 {
2416 int formal_id = ipa_get_jf_pass_through_formal_id (src);
2417 enum tree_code operation;
2418 operation = ipa_get_jf_pass_through_operation (src);
2419
2420 if (operation == NOP_EXPR)
2421 {
2422 bool agg_p, type_p;
2423 agg_p = dst_agg_p
2424 && ipa_get_jf_pass_through_agg_preserved (src);
2425 type_p = ipa_get_jf_pass_through_type_preserved (src)
2426 && ipa_get_jf_pass_through_type_preserved (dst);
2427 ipa_set_jf_simple_pass_through (dst, formal_id,
2428 agg_p, type_p);
2429 }
2430 else
2431 {
2432 tree operand = ipa_get_jf_pass_through_operand (src);
2433 ipa_set_jf_arith_pass_through (dst, formal_id, operand,
2434 operation);
2435 }
2436 break;
2437 }
2438 case IPA_JF_ANCESTOR:
2439 {
2440 bool agg_p, type_p;
2441 agg_p = dst_agg_p
2442 && ipa_get_jf_ancestor_agg_preserved (src);
2443 type_p = ipa_get_jf_ancestor_type_preserved (src)
2444 && ipa_get_jf_pass_through_type_preserved (dst);
2445 ipa_set_ancestor_jf (dst,
2446 ipa_get_jf_ancestor_offset (src),
2447 ipa_get_jf_ancestor_type (src),
2448 ipa_get_jf_ancestor_formal_id (src),
2449 agg_p, type_p);
2450 break;
2451 }
2452 default:
2453 gcc_unreachable ();
2454 }
8b7773a4
MJ
2455
2456 if (src->agg.items
b8f6e610 2457 && (dst_agg_p || !src->agg.by_ref))
8b7773a4
MJ
2458 {
2459 /* Currently we do not produce clobber aggregate jump
2460 functions, replace with merging when we do. */
2461 gcc_assert (!dst->agg.items);
2462
2463 dst->agg.by_ref = src->agg.by_ref;
9771b263 2464 dst->agg.items = vec_safe_copy (src->agg.items);
8b7773a4 2465 }
b258210c
MJ
2466 }
2467 else
2468 dst->type = IPA_JF_UNKNOWN;
3e293154 2469 }
b258210c
MJ
2470 }
2471}
2472
2473/* If TARGET is an addr_expr of a function declaration, make it the destination
81fa35bd 2474 of an indirect edge IE and return the edge. Otherwise, return NULL. */
b258210c 2475
3949c4a7 2476struct cgraph_edge *
81fa35bd 2477ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target)
b258210c
MJ
2478{
2479 struct cgraph_node *callee;
0f378cb5 2480 struct inline_edge_summary *es = inline_edge_summary (ie);
48b1474e 2481 bool unreachable = false;
b258210c 2482
ceeffab0
MJ
2483 if (TREE_CODE (target) == ADDR_EXPR)
2484 target = TREE_OPERAND (target, 0);
b258210c 2485 if (TREE_CODE (target) != FUNCTION_DECL)
a0a7b611
JH
2486 {
2487 target = canonicalize_constructor_val (target, NULL);
2488 if (!target || TREE_CODE (target) != FUNCTION_DECL)
2489 {
c13bc3d9
MJ
2490 if (ie->indirect_info->member_ptr)
2491 /* Member pointer call that goes through a VMT lookup. */
2492 return NULL;
2493
2b5f0895
XDL
2494 if (dump_enabled_p ())
2495 {
2496 location_t loc = gimple_location (ie->call_stmt);
2497 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
2498 "discovered direct call to non-function in %s/%i, "
2499 "making it __builtin_unreachable\n",
2500 ie->caller->name (),
2501 ie->caller->order);
2502 }
48b1474e
MJ
2503 target = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
2504 callee = cgraph_get_create_node (target);
2505 unreachable = true;
a0a7b611 2506 }
48b1474e
MJ
2507 else
2508 callee = cgraph_get_node (target);
a0a7b611 2509 }
48b1474e
MJ
2510 else
2511 callee = cgraph_get_node (target);
a0a7b611
JH
2512
2513 /* Because may-edges are not explicitely represented and vtable may be external,
2514 we may create the first reference to the object in the unit. */
2515 if (!callee || callee->global.inlined_to)
2516 {
a0a7b611
JH
2517
2518 /* We are better to ensure we can refer to it.
2519 In the case of static functions we are out of luck, since we already
2520 removed its body. In the case of public functions we may or may
2521 not introduce the reference. */
2522 if (!canonicalize_constructor_val (target, NULL)
2523 || !TREE_PUBLIC (target))
2524 {
2525 if (dump_file)
2526 fprintf (dump_file, "ipa-prop: Discovered call to a known target "
2527 "(%s/%i -> %s/%i) but can not refer to it. Giving up.\n",
fec39fa6 2528 xstrdup (ie->caller->name ()),
67348ccc 2529 ie->caller->order,
fec39fa6 2530 xstrdup (ie->callee->name ()),
67348ccc 2531 ie->callee->order);
a0a7b611
JH
2532 return NULL;
2533 }
6f99e449 2534 callee = cgraph_get_create_node (target);
a0a7b611 2535 }
2b5f0895
XDL
2536
2537 if (!dbg_cnt (devirt))
2538 return NULL;
2539
1dbee8c9 2540 ipa_check_create_node_params ();
ceeffab0 2541
81fa35bd
MJ
2542 /* We can not make edges to inline clones. It is bug that someone removed
2543 the cgraph node too early. */
17afc0fe
JH
2544 gcc_assert (!callee->global.inlined_to);
2545
48b1474e 2546 if (dump_file && !unreachable)
b258210c
MJ
2547 {
2548 fprintf (dump_file, "ipa-prop: Discovered %s call to a known target "
ceeffab0 2549 "(%s/%i -> %s/%i), for stmt ",
b258210c 2550 ie->indirect_info->polymorphic ? "a virtual" : "an indirect",
fec39fa6 2551 xstrdup (ie->caller->name ()),
67348ccc 2552 ie->caller->order,
fec39fa6 2553 xstrdup (callee->name ()),
67348ccc 2554 callee->order);
b258210c
MJ
2555 if (ie->call_stmt)
2556 print_gimple_stmt (dump_file, ie->call_stmt, 2, TDF_SLIM);
2557 else
2558 fprintf (dump_file, "with uid %i\n", ie->lto_stmt_uid);
042ae7d2 2559 }
2b5f0895
XDL
2560 if (dump_enabled_p ())
2561 {
2562 location_t loc = gimple_location (ie->call_stmt);
2563 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
2564 "converting indirect call in %s to direct call to %s\n",
2565 ie->caller->name (), callee->name ());
2566 }
042ae7d2
JH
2567 ie = cgraph_make_edge_direct (ie, callee);
2568 es = inline_edge_summary (ie);
2569 es->call_stmt_size -= (eni_size_weights.indirect_call_cost
2570 - eni_size_weights.call_cost);
2571 es->call_stmt_time -= (eni_time_weights.indirect_call_cost
2572 - eni_time_weights.call_cost);
749aa96d 2573
b258210c 2574 return ie;
3e293154
MJ
2575}
2576
8b7773a4
MJ
2577/* Retrieve value from aggregate jump function AGG for the given OFFSET or
2578 return NULL if there is not any. BY_REF specifies whether the value has to
2579 be passed by reference or by value. */
2580
2581tree
2582ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *agg,
2583 HOST_WIDE_INT offset, bool by_ref)
2584{
2585 struct ipa_agg_jf_item *item;
2586 int i;
2587
2588 if (by_ref != agg->by_ref)
2589 return NULL;
2590
9771b263 2591 FOR_EACH_VEC_SAFE_ELT (agg->items, i, item)
2c9561b5
MJ
2592 if (item->offset == offset)
2593 {
2594 /* Currently we do not have clobber values, return NULL for them once
2595 we do. */
2596 gcc_checking_assert (is_gimple_ip_invariant (item->value));
2597 return item->value;
2598 }
8b7773a4
MJ
2599 return NULL;
2600}
2601
4502fe8d 2602/* Remove a reference to SYMBOL from the list of references of a node given by
568cda29
MJ
2603 reference description RDESC. Return true if the reference has been
2604 successfully found and removed. */
4502fe8d 2605
568cda29 2606static bool
5e20cdc9 2607remove_described_reference (symtab_node *symbol, struct ipa_cst_ref_desc *rdesc)
4502fe8d
MJ
2608{
2609 struct ipa_ref *to_del;
2610 struct cgraph_edge *origin;
2611
2612 origin = rdesc->cs;
a854f856
MJ
2613 if (!origin)
2614 return false;
67348ccc 2615 to_del = ipa_find_reference (origin->caller, symbol,
042ae7d2 2616 origin->call_stmt, origin->lto_stmt_uid);
568cda29
MJ
2617 if (!to_del)
2618 return false;
2619
4502fe8d
MJ
2620 ipa_remove_reference (to_del);
2621 if (dump_file)
2622 fprintf (dump_file, "ipa-prop: Removed a reference from %s/%i to %s.\n",
fec39fa6
TS
2623 xstrdup (origin->caller->name ()),
2624 origin->caller->order, xstrdup (symbol->name ()));
568cda29 2625 return true;
4502fe8d
MJ
2626}
2627
2628/* If JFUNC has a reference description with refcount different from
2629 IPA_UNDESCRIBED_USE, return the reference description, otherwise return
2630 NULL. JFUNC must be a constant jump function. */
2631
2632static struct ipa_cst_ref_desc *
2633jfunc_rdesc_usable (struct ipa_jump_func *jfunc)
2634{
2635 struct ipa_cst_ref_desc *rdesc = ipa_get_jf_constant_rdesc (jfunc);
2636 if (rdesc && rdesc->refcount != IPA_UNDESCRIBED_USE)
2637 return rdesc;
2638 else
2639 return NULL;
2640}
2641
568cda29
MJ
2642/* If the value of constant jump function JFUNC is an address of a function
2643 declaration, return the associated call graph node. Otherwise return
2644 NULL. */
2645
2646static cgraph_node *
2647cgraph_node_for_jfunc (struct ipa_jump_func *jfunc)
2648{
2649 gcc_checking_assert (jfunc->type == IPA_JF_CONST);
2650 tree cst = ipa_get_jf_constant (jfunc);
2651 if (TREE_CODE (cst) != ADDR_EXPR
2652 || TREE_CODE (TREE_OPERAND (cst, 0)) != FUNCTION_DECL)
2653 return NULL;
2654
2655 return cgraph_get_node (TREE_OPERAND (cst, 0));
2656}
2657
2658
2659/* If JFUNC is a constant jump function with a usable rdesc, decrement its
2660 refcount and if it hits zero, remove reference to SYMBOL from the caller of
2661 the edge specified in the rdesc. Return false if either the symbol or the
2662 reference could not be found, otherwise return true. */
2663
2664static bool
2665try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc)
2666{
2667 struct ipa_cst_ref_desc *rdesc;
2668 if (jfunc->type == IPA_JF_CONST
2669 && (rdesc = jfunc_rdesc_usable (jfunc))
2670 && --rdesc->refcount == 0)
2671 {
5e20cdc9 2672 symtab_node *symbol = cgraph_node_for_jfunc (jfunc);
568cda29
MJ
2673 if (!symbol)
2674 return false;
2675
2676 return remove_described_reference (symbol, rdesc);
2677 }
2678 return true;
2679}
2680
b258210c
MJ
2681/* Try to find a destination for indirect edge IE that corresponds to a simple
2682 call or a call of a member function pointer and where the destination is a
2683 pointer formal parameter described by jump function JFUNC. If it can be
d250540a
MJ
2684 determined, return the newly direct edge, otherwise return NULL.
2685 NEW_ROOT_INFO is the node info that JFUNC lattices are relative to. */
be95e2b9 2686
b258210c
MJ
2687static struct cgraph_edge *
2688try_make_edge_direct_simple_call (struct cgraph_edge *ie,
d250540a
MJ
2689 struct ipa_jump_func *jfunc,
2690 struct ipa_node_params *new_root_info)
b258210c 2691{
4502fe8d 2692 struct cgraph_edge *cs;
b258210c 2693 tree target;
042ae7d2 2694 bool agg_contents = ie->indirect_info->agg_contents;
b258210c 2695
8b7773a4 2696 if (ie->indirect_info->agg_contents)
d250540a
MJ
2697 target = ipa_find_agg_cst_for_param (&jfunc->agg,
2698 ie->indirect_info->offset,
2699 ie->indirect_info->by_ref);
b258210c 2700 else
d250540a
MJ
2701 target = ipa_value_from_jfunc (new_root_info, jfunc);
2702 if (!target)
2703 return NULL;
4502fe8d
MJ
2704 cs = ipa_make_edge_direct_to_target (ie, target);
2705
a12cd2db 2706 if (cs && !agg_contents)
568cda29
MJ
2707 {
2708 bool ok;
2709 gcc_checking_assert (cs->callee
ae6d0907
MJ
2710 && (cs != ie
2711 || jfunc->type != IPA_JF_CONST
568cda29
MJ
2712 || !cgraph_node_for_jfunc (jfunc)
2713 || cs->callee == cgraph_node_for_jfunc (jfunc)));
2714 ok = try_decrement_rdesc_refcount (jfunc);
2715 gcc_checking_assert (ok);
2716 }
4502fe8d
MJ
2717
2718 return cs;
b258210c
MJ
2719}
2720
d250540a
MJ
2721/* Try to find a destination for indirect edge IE that corresponds to a virtual
2722 call based on a formal parameter which is described by jump function JFUNC
2723 and if it can be determined, make it direct and return the direct edge.
2724 Otherwise, return NULL. NEW_ROOT_INFO is the node info that JFUNC lattices
2725 are relative to. */
b258210c
MJ
2726
2727static struct cgraph_edge *
2728try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
d250540a
MJ
2729 struct ipa_jump_func *jfunc,
2730 struct ipa_node_params *new_root_info)
3e293154 2731{
9de2f554 2732 tree binfo, target;
85942f45
JH
2733
2734 if (!flag_devirtualize)
2735 return NULL;
b258210c 2736
9de2f554 2737 /* First try to do lookup via known virtual table pointer value. */
85942f45
JH
2738 if (!ie->indirect_info->by_ref)
2739 {
9de2f554
JH
2740 tree vtable;
2741 unsigned HOST_WIDE_INT offset;
85942f45
JH
2742 tree t = ipa_find_agg_cst_for_param (&jfunc->agg,
2743 ie->indirect_info->offset,
2744 true);
9de2f554
JH
2745 if (t && vtable_pointer_value_to_vtable (t, &vtable, &offset))
2746 {
2747 target = gimple_get_virt_method_for_vtable (ie->indirect_info->otr_token,
2748 vtable, offset);
2749 if (target)
2750 {
2751 if ((TREE_CODE (TREE_TYPE (target)) == FUNCTION_TYPE
2752 && DECL_FUNCTION_CODE (target) == BUILT_IN_UNREACHABLE)
2753 || !possible_polymorphic_call_target_p
2754 (ie, cgraph_get_node (target)))
2755 {
2756 if (dump_file)
2757 fprintf (dump_file,
2758 "Type inconsident devirtualization: %s/%i->%s\n",
2759 ie->caller->name (), ie->caller->order,
2760 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (target)));
2761 target = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
2762 cgraph_get_create_node (target);
2763 }
2764 return ipa_make_edge_direct_to_target (ie, target);
2765 }
2766 }
85942f45
JH
2767 }
2768
9de2f554 2769 binfo = ipa_value_from_jfunc (new_root_info, jfunc);
d250540a 2770
da942ca0 2771 if (!binfo)
b258210c 2772 return NULL;
3e293154 2773
da942ca0
JH
2774 if (TREE_CODE (binfo) != TREE_BINFO)
2775 {
5bccb77a
JH
2776 ipa_polymorphic_call_context context;
2777 vec <cgraph_node *>targets;
2778 bool final;
2779
2780 if (!get_polymorphic_call_info_from_invariant
2781 (&context, binfo, ie->indirect_info->otr_type,
2782 ie->indirect_info->offset))
2783 return NULL;
2784 targets = possible_polymorphic_call_targets
2785 (ie->indirect_info->otr_type,
2786 ie->indirect_info->otr_token,
2787 context, &final);
2788 if (!final || targets.length () > 1)
85942f45 2789 return NULL;
5bccb77a
JH
2790 if (targets.length () == 1)
2791 target = targets[0]->decl;
2792 else
2793 {
2794 target = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
2795 cgraph_get_create_node (target);
2796 }
da942ca0 2797 }
b258210c 2798 else
5bccb77a
JH
2799 {
2800 binfo = get_binfo_at_offset (binfo, ie->indirect_info->offset,
2801 ie->indirect_info->otr_type);
2802 if (binfo)
2803 target = gimple_get_virt_method_for_binfo (ie->indirect_info->otr_token,
2804 binfo);
2805 else
2806 return NULL;
2807 }
b258210c
MJ
2808
2809 if (target)
450ad0cd
JH
2810 {
2811#ifdef ENABLE_CHECKING
2812 gcc_assert (possible_polymorphic_call_target_p
2813 (ie, cgraph_get_node (target)));
2814#endif
2815 return ipa_make_edge_direct_to_target (ie, target);
2816 }
b258210c
MJ
2817 else
2818 return NULL;
3e293154
MJ
2819}
2820
2821/* Update the param called notes associated with NODE when CS is being inlined,
2822 assuming NODE is (potentially indirectly) inlined into CS->callee.
2823 Moreover, if the callee is discovered to be constant, create a new cgraph
e56f5f3e 2824 edge for it. Newly discovered indirect edges will be added to *NEW_EDGES,
f8e2a1ed 2825 unless NEW_EDGES is NULL. Return true iff a new edge(s) were created. */
be95e2b9 2826
f8e2a1ed 2827static bool
e33c6cd6
MJ
2828update_indirect_edges_after_inlining (struct cgraph_edge *cs,
2829 struct cgraph_node *node,
9771b263 2830 vec<cgraph_edge_p> *new_edges)
3e293154 2831{
9e97ff61 2832 struct ipa_edge_args *top;
b258210c 2833 struct cgraph_edge *ie, *next_ie, *new_direct_edge;
d250540a 2834 struct ipa_node_params *new_root_info;
f8e2a1ed 2835 bool res = false;
3e293154 2836
e33c6cd6 2837 ipa_check_create_edge_args ();
9e97ff61 2838 top = IPA_EDGE_REF (cs);
d250540a
MJ
2839 new_root_info = IPA_NODE_REF (cs->caller->global.inlined_to
2840 ? cs->caller->global.inlined_to
2841 : cs->caller);
e33c6cd6
MJ
2842
2843 for (ie = node->indirect_calls; ie; ie = next_ie)
3e293154 2844 {
e33c6cd6 2845 struct cgraph_indirect_call_info *ici = ie->indirect_info;
3e293154 2846 struct ipa_jump_func *jfunc;
8b7773a4 2847 int param_index;
3e293154 2848
e33c6cd6 2849 next_ie = ie->next_callee;
3e293154 2850
5f902d76
JH
2851 if (ici->param_index == -1)
2852 continue;
e33c6cd6 2853
3e293154 2854 /* We must check range due to calls with variable number of arguments: */
e33c6cd6 2855 if (ici->param_index >= ipa_get_cs_argument_count (top))
3e293154 2856 {
5ee53a06 2857 ici->param_index = -1;
3e293154
MJ
2858 continue;
2859 }
2860
8b7773a4
MJ
2861 param_index = ici->param_index;
2862 jfunc = ipa_get_ith_jump_func (top, param_index);
5ee53a06
JH
2863
2864 if (!flag_indirect_inlining)
36b72910
JH
2865 new_direct_edge = NULL;
2866 else if (ici->polymorphic)
d250540a
MJ
2867 new_direct_edge = try_make_edge_direct_virtual_call (ie, jfunc,
2868 new_root_info);
b258210c 2869 else
d250540a
MJ
2870 new_direct_edge = try_make_edge_direct_simple_call (ie, jfunc,
2871 new_root_info);
042ae7d2
JH
2872 /* If speculation was removed, then we need to do nothing. */
2873 if (new_direct_edge && new_direct_edge != ie)
2874 {
2875 new_direct_edge->indirect_inlining_edge = 1;
2876 top = IPA_EDGE_REF (cs);
2877 res = true;
2878 }
2879 else if (new_direct_edge)
685b0d13 2880 {
b258210c 2881 new_direct_edge->indirect_inlining_edge = 1;
89faf322
RG
2882 if (new_direct_edge->call_stmt)
2883 new_direct_edge->call_stmt_cannot_inline_p
4de09b85
DC
2884 = !gimple_check_call_matching_types (
2885 new_direct_edge->call_stmt,
67348ccc 2886 new_direct_edge->callee->decl, false);
b258210c
MJ
2887 if (new_edges)
2888 {
9771b263 2889 new_edges->safe_push (new_direct_edge);
b258210c
MJ
2890 res = true;
2891 }
042ae7d2 2892 top = IPA_EDGE_REF (cs);
685b0d13 2893 }
36b72910
JH
2894 else if (jfunc->type == IPA_JF_PASS_THROUGH
2895 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
2896 {
8a2256dd
MJ
2897 if ((ici->agg_contents
2898 && !ipa_get_jf_pass_through_agg_preserved (jfunc))
2899 || (ici->polymorphic
2900 && !ipa_get_jf_pass_through_type_preserved (jfunc)))
36b72910
JH
2901 ici->param_index = -1;
2902 else
2903 ici->param_index = ipa_get_jf_pass_through_formal_id (jfunc);
2904 }
2905 else if (jfunc->type == IPA_JF_ANCESTOR)
2906 {
8a2256dd
MJ
2907 if ((ici->agg_contents
2908 && !ipa_get_jf_ancestor_agg_preserved (jfunc))
2909 || (ici->polymorphic
2910 && !ipa_get_jf_ancestor_type_preserved (jfunc)))
36b72910
JH
2911 ici->param_index = -1;
2912 else
2913 {
2914 ici->param_index = ipa_get_jf_ancestor_formal_id (jfunc);
68377e53
JH
2915 if (ipa_get_jf_ancestor_offset (jfunc))
2916 ici->outer_type = NULL;
36b72910
JH
2917 ici->offset += ipa_get_jf_ancestor_offset (jfunc);
2918 }
2919 }
2920 else
2921 /* Either we can find a destination for this edge now or never. */
2922 ici->param_index = -1;
3e293154 2923 }
e33c6cd6 2924
f8e2a1ed 2925 return res;
3e293154
MJ
2926}
2927
2928/* Recursively traverse subtree of NODE (including node) made of inlined
2929 cgraph_edges when CS has been inlined and invoke
e33c6cd6 2930 update_indirect_edges_after_inlining on all nodes and
3e293154
MJ
2931 update_jump_functions_after_inlining on all non-inlined edges that lead out
2932 of this subtree. Newly discovered indirect edges will be added to
f8e2a1ed
MJ
2933 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were
2934 created. */
be95e2b9 2935
f8e2a1ed 2936static bool
3e293154
MJ
2937propagate_info_to_inlined_callees (struct cgraph_edge *cs,
2938 struct cgraph_node *node,
9771b263 2939 vec<cgraph_edge_p> *new_edges)
3e293154
MJ
2940{
2941 struct cgraph_edge *e;
f8e2a1ed 2942 bool res;
3e293154 2943
e33c6cd6 2944 res = update_indirect_edges_after_inlining (cs, node, new_edges);
3e293154
MJ
2945
2946 for (e = node->callees; e; e = e->next_callee)
2947 if (!e->inline_failed)
f8e2a1ed 2948 res |= propagate_info_to_inlined_callees (cs, e->callee, new_edges);
3e293154
MJ
2949 else
2950 update_jump_functions_after_inlining (cs, e);
5ee53a06
JH
2951 for (e = node->indirect_calls; e; e = e->next_callee)
2952 update_jump_functions_after_inlining (cs, e);
f8e2a1ed
MJ
2953
2954 return res;
3e293154
MJ
2955}
2956
4502fe8d
MJ
2957/* Combine two controlled uses counts as done during inlining. */
2958
2959static int
2960combine_controlled_uses_counters (int c, int d)
2961{
2962 if (c == IPA_UNDESCRIBED_USE || d == IPA_UNDESCRIBED_USE)
2963 return IPA_UNDESCRIBED_USE;
2964 else
2965 return c + d - 1;
2966}
2967
2968/* Propagate number of controlled users from CS->caleee to the new root of the
2969 tree of inlined nodes. */
2970
2971static void
2972propagate_controlled_uses (struct cgraph_edge *cs)
2973{
2974 struct ipa_edge_args *args = IPA_EDGE_REF (cs);
2975 struct cgraph_node *new_root = cs->caller->global.inlined_to
2976 ? cs->caller->global.inlined_to : cs->caller;
2977 struct ipa_node_params *new_root_info = IPA_NODE_REF (new_root);
2978 struct ipa_node_params *old_root_info = IPA_NODE_REF (cs->callee);
2979 int count, i;
2980
2981 count = MIN (ipa_get_cs_argument_count (args),
2982 ipa_get_param_count (old_root_info));
2983 for (i = 0; i < count; i++)
2984 {
2985 struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
2986 struct ipa_cst_ref_desc *rdesc;
2987
2988 if (jf->type == IPA_JF_PASS_THROUGH)
2989 {
2990 int src_idx, c, d;
2991 src_idx = ipa_get_jf_pass_through_formal_id (jf);
2992 c = ipa_get_controlled_uses (new_root_info, src_idx);
2993 d = ipa_get_controlled_uses (old_root_info, i);
2994
2995 gcc_checking_assert (ipa_get_jf_pass_through_operation (jf)
2996 == NOP_EXPR || c == IPA_UNDESCRIBED_USE);
2997 c = combine_controlled_uses_counters (c, d);
2998 ipa_set_controlled_uses (new_root_info, src_idx, c);
2999 if (c == 0 && new_root_info->ipcp_orig_node)
3000 {
3001 struct cgraph_node *n;
3002 struct ipa_ref *ref;
3003 tree t = new_root_info->known_vals[src_idx];
3004
3005 if (t && TREE_CODE (t) == ADDR_EXPR
3006 && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
3007 && (n = cgraph_get_node (TREE_OPERAND (t, 0)))
67348ccc
DM
3008 && (ref = ipa_find_reference (new_root,
3009 n, NULL, 0)))
4502fe8d
MJ
3010 {
3011 if (dump_file)
3012 fprintf (dump_file, "ipa-prop: Removing cloning-created "
3013 "reference from %s/%i to %s/%i.\n",
fec39fa6 3014 xstrdup (new_root->name ()),
67348ccc 3015 new_root->order,
fec39fa6 3016 xstrdup (n->name ()), n->order);
4502fe8d
MJ
3017 ipa_remove_reference (ref);
3018 }
3019 }
3020 }
3021 else if (jf->type == IPA_JF_CONST
3022 && (rdesc = jfunc_rdesc_usable (jf)))
3023 {
3024 int d = ipa_get_controlled_uses (old_root_info, i);
3025 int c = rdesc->refcount;
3026 rdesc->refcount = combine_controlled_uses_counters (c, d);
3027 if (rdesc->refcount == 0)
3028 {
3029 tree cst = ipa_get_jf_constant (jf);
3030 struct cgraph_node *n;
3031 gcc_checking_assert (TREE_CODE (cst) == ADDR_EXPR
3032 && TREE_CODE (TREE_OPERAND (cst, 0))
3033 == FUNCTION_DECL);
3034 n = cgraph_get_node (TREE_OPERAND (cst, 0));
3035 if (n)
3036 {
3037 struct cgraph_node *clone;
568cda29 3038 bool ok;
67348ccc 3039 ok = remove_described_reference (n, rdesc);
568cda29 3040 gcc_checking_assert (ok);
4502fe8d
MJ
3041
3042 clone = cs->caller;
3043 while (clone->global.inlined_to
3044 && clone != rdesc->cs->caller
3045 && IPA_NODE_REF (clone)->ipcp_orig_node)
3046 {
3047 struct ipa_ref *ref;
67348ccc
DM
3048 ref = ipa_find_reference (clone,
3049 n, NULL, 0);
4502fe8d
MJ
3050 if (ref)
3051 {
3052 if (dump_file)
3053 fprintf (dump_file, "ipa-prop: Removing "
3054 "cloning-created reference "
3055 "from %s/%i to %s/%i.\n",
fec39fa6 3056 xstrdup (clone->name ()),
67348ccc 3057 clone->order,
fec39fa6 3058 xstrdup (n->name ()),
67348ccc 3059 n->order);
4502fe8d
MJ
3060 ipa_remove_reference (ref);
3061 }
3062 clone = clone->callers->caller;
3063 }
3064 }
3065 }
3066 }
3067 }
3068
3069 for (i = ipa_get_param_count (old_root_info);
3070 i < ipa_get_cs_argument_count (args);
3071 i++)
3072 {
3073 struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
3074
3075 if (jf->type == IPA_JF_CONST)
3076 {
3077 struct ipa_cst_ref_desc *rdesc = jfunc_rdesc_usable (jf);
3078 if (rdesc)
3079 rdesc->refcount = IPA_UNDESCRIBED_USE;
3080 }
3081 else if (jf->type == IPA_JF_PASS_THROUGH)
3082 ipa_set_controlled_uses (new_root_info,
3083 jf->value.pass_through.formal_id,
3084 IPA_UNDESCRIBED_USE);
3085 }
3086}
3087
3e293154
MJ
3088/* Update jump functions and call note functions on inlining the call site CS.
3089 CS is expected to lead to a node already cloned by
3090 cgraph_clone_inline_nodes. Newly discovered indirect edges will be added to
f8e2a1ed
MJ
3091 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were +
3092 created. */
be95e2b9 3093
f8e2a1ed 3094bool
3e293154 3095ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
9771b263 3096 vec<cgraph_edge_p> *new_edges)
3e293154 3097{
5ee53a06 3098 bool changed;
f8e2a1ed
MJ
3099 /* Do nothing if the preparation phase has not been carried out yet
3100 (i.e. during early inlining). */
9771b263 3101 if (!ipa_node_params_vector.exists ())
f8e2a1ed
MJ
3102 return false;
3103 gcc_assert (ipa_edge_args_vector);
3104
4502fe8d 3105 propagate_controlled_uses (cs);
5ee53a06
JH
3106 changed = propagate_info_to_inlined_callees (cs, cs->callee, new_edges);
3107
5ee53a06 3108 return changed;
518dc859
RL
3109}
3110
771578a0
MJ
3111/* Frees all dynamically allocated structures that the argument info points
3112 to. */
be95e2b9 3113
518dc859 3114void
771578a0 3115ipa_free_edge_args_substructures (struct ipa_edge_args *args)
518dc859 3116{
9771b263 3117 vec_free (args->jump_functions);
771578a0 3118 memset (args, 0, sizeof (*args));
518dc859
RL
3119}
3120
771578a0 3121/* Free all ipa_edge structures. */
be95e2b9 3122
518dc859 3123void
771578a0 3124ipa_free_all_edge_args (void)
518dc859 3125{
771578a0
MJ
3126 int i;
3127 struct ipa_edge_args *args;
518dc859 3128
9771b263
DN
3129 if (!ipa_edge_args_vector)
3130 return;
3131
3132 FOR_EACH_VEC_ELT (*ipa_edge_args_vector, i, args)
771578a0
MJ
3133 ipa_free_edge_args_substructures (args);
3134
9771b263 3135 vec_free (ipa_edge_args_vector);
518dc859
RL
3136}
3137
771578a0
MJ
3138/* Frees all dynamically allocated structures that the param info points
3139 to. */
be95e2b9 3140
518dc859 3141void
771578a0 3142ipa_free_node_params_substructures (struct ipa_node_params *info)
518dc859 3143{
9771b263 3144 info->descriptors.release ();
310bc633
MJ
3145 free (info->lattices);
3146 /* Lattice values and their sources are deallocated with their alocation
3147 pool. */
9771b263 3148 info->known_vals.release ();
771578a0 3149 memset (info, 0, sizeof (*info));
518dc859
RL
3150}
3151
771578a0 3152/* Free all ipa_node_params structures. */
be95e2b9 3153
518dc859 3154void
771578a0 3155ipa_free_all_node_params (void)
518dc859 3156{
771578a0
MJ
3157 int i;
3158 struct ipa_node_params *info;
518dc859 3159
9771b263 3160 FOR_EACH_VEC_ELT (ipa_node_params_vector, i, info)
771578a0
MJ
3161 ipa_free_node_params_substructures (info);
3162
9771b263 3163 ipa_node_params_vector.release ();
771578a0
MJ
3164}
3165
2c9561b5
MJ
3166/* Set the aggregate replacements of NODE to be AGGVALS. */
3167
3168void
3169ipa_set_node_agg_value_chain (struct cgraph_node *node,
3170 struct ipa_agg_replacement_value *aggvals)
3171{
9771b263
DN
3172 if (vec_safe_length (ipa_node_agg_replacements) <= (unsigned) cgraph_max_uid)
3173 vec_safe_grow_cleared (ipa_node_agg_replacements, cgraph_max_uid + 1);
2c9561b5 3174
9771b263 3175 (*ipa_node_agg_replacements)[node->uid] = aggvals;
2c9561b5
MJ
3176}
3177
771578a0 3178/* Hook that is called by cgraph.c when an edge is removed. */
be95e2b9 3179
771578a0 3180static void
5c0466b5 3181ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
771578a0 3182{
568cda29
MJ
3183 struct ipa_edge_args *args;
3184
3185 /* During IPA-CP updating we can be called on not-yet analyzed clones. */
9771b263 3186 if (vec_safe_length (ipa_edge_args_vector) <= (unsigned)cs->uid)
c6f7cfc1 3187 return;
568cda29
MJ
3188
3189 args = IPA_EDGE_REF (cs);
3190 if (args->jump_functions)
3191 {
3192 struct ipa_jump_func *jf;
3193 int i;
3194 FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
a854f856
MJ
3195 {
3196 struct ipa_cst_ref_desc *rdesc;
3197 try_decrement_rdesc_refcount (jf);
3198 if (jf->type == IPA_JF_CONST
3199 && (rdesc = ipa_get_jf_constant_rdesc (jf))
3200 && rdesc->cs == cs)
3201 rdesc->cs = NULL;
3202 }
568cda29
MJ
3203 }
3204
771578a0 3205 ipa_free_edge_args_substructures (IPA_EDGE_REF (cs));
518dc859
RL
3206}
3207
771578a0 3208/* Hook that is called by cgraph.c when a node is removed. */
be95e2b9 3209
771578a0 3210static void
5c0466b5 3211ipa_node_removal_hook (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
771578a0 3212{
dd6d1ad7 3213 /* During IPA-CP updating we can be called on not-yet analyze clones. */
9771b263 3214 if (ipa_node_params_vector.length () > (unsigned)node->uid)
2c9561b5 3215 ipa_free_node_params_substructures (IPA_NODE_REF (node));
9771b263
DN
3216 if (vec_safe_length (ipa_node_agg_replacements) > (unsigned)node->uid)
3217 (*ipa_node_agg_replacements)[(unsigned)node->uid] = NULL;
771578a0
MJ
3218}
3219
8b7773a4 3220/* Hook that is called by cgraph.c when an edge is duplicated. */
be95e2b9 3221
771578a0
MJ
3222static void
3223ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
f8e2a1ed 3224 __attribute__((unused)) void *data)
771578a0
MJ
3225{
3226 struct ipa_edge_args *old_args, *new_args;
8b7773a4 3227 unsigned int i;
771578a0
MJ
3228
3229 ipa_check_create_edge_args ();
3230
3231 old_args = IPA_EDGE_REF (src);
3232 new_args = IPA_EDGE_REF (dst);
3233
9771b263 3234 new_args->jump_functions = vec_safe_copy (old_args->jump_functions);
8b7773a4 3235
9771b263 3236 for (i = 0; i < vec_safe_length (old_args->jump_functions); i++)
4502fe8d
MJ
3237 {
3238 struct ipa_jump_func *src_jf = ipa_get_ith_jump_func (old_args, i);
3239 struct ipa_jump_func *dst_jf = ipa_get_ith_jump_func (new_args, i);
3240
3241 dst_jf->agg.items = vec_safe_copy (dst_jf->agg.items);
3242
3243 if (src_jf->type == IPA_JF_CONST)
3244 {
3245 struct ipa_cst_ref_desc *src_rdesc = jfunc_rdesc_usable (src_jf);
3246
3247 if (!src_rdesc)
3248 dst_jf->value.constant.rdesc = NULL;
568cda29
MJ
3249 else if (src->caller == dst->caller)
3250 {
3251 struct ipa_ref *ref;
5e20cdc9 3252 symtab_node *n = cgraph_node_for_jfunc (src_jf);
568cda29 3253 gcc_checking_assert (n);
67348ccc 3254 ref = ipa_find_reference (src->caller, n,
568cda29
MJ
3255 src->call_stmt, src->lto_stmt_uid);
3256 gcc_checking_assert (ref);
67348ccc 3257 ipa_clone_ref (ref, dst->caller, ref->stmt);
568cda29
MJ
3258
3259 gcc_checking_assert (ipa_refdesc_pool);
3260 struct ipa_cst_ref_desc *dst_rdesc
3261 = (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
3262 dst_rdesc->cs = dst;
3263 dst_rdesc->refcount = src_rdesc->refcount;
3264 dst_rdesc->next_duplicate = NULL;
3265 dst_jf->value.constant.rdesc = dst_rdesc;
3266 }
4502fe8d
MJ
3267 else if (src_rdesc->cs == src)
3268 {
3269 struct ipa_cst_ref_desc *dst_rdesc;
3270 gcc_checking_assert (ipa_refdesc_pool);
3271 dst_rdesc
3272 = (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
3273 dst_rdesc->cs = dst;
4502fe8d 3274 dst_rdesc->refcount = src_rdesc->refcount;
2fd0985c
MJ
3275 dst_rdesc->next_duplicate = src_rdesc->next_duplicate;
3276 src_rdesc->next_duplicate = dst_rdesc;
4502fe8d
MJ
3277 dst_jf->value.constant.rdesc = dst_rdesc;
3278 }
3279 else
3280 {
3281 struct ipa_cst_ref_desc *dst_rdesc;
3282 /* This can happen during inlining, when a JFUNC can refer to a
3283 reference taken in a function up in the tree of inline clones.
3284 We need to find the duplicate that refers to our tree of
3285 inline clones. */
3286
3287 gcc_assert (dst->caller->global.inlined_to);
3288 for (dst_rdesc = src_rdesc->next_duplicate;
3289 dst_rdesc;
3290 dst_rdesc = dst_rdesc->next_duplicate)
2fd0985c
MJ
3291 {
3292 struct cgraph_node *top;
3293 top = dst_rdesc->cs->caller->global.inlined_to
3294 ? dst_rdesc->cs->caller->global.inlined_to
3295 : dst_rdesc->cs->caller;
3296 if (dst->caller->global.inlined_to == top)
3297 break;
3298 }
44a60244 3299 gcc_assert (dst_rdesc);
4502fe8d
MJ
3300 dst_jf->value.constant.rdesc = dst_rdesc;
3301 }
3302 }
3303 }
771578a0
MJ
3304}
3305
3306/* Hook that is called by cgraph.c when a node is duplicated. */
be95e2b9 3307
771578a0
MJ
3308static void
3309ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
10a5dd5d 3310 ATTRIBUTE_UNUSED void *data)
771578a0
MJ
3311{
3312 struct ipa_node_params *old_info, *new_info;
2c9561b5 3313 struct ipa_agg_replacement_value *old_av, *new_av;
771578a0
MJ
3314
3315 ipa_check_create_node_params ();
3316 old_info = IPA_NODE_REF (src);
3317 new_info = IPA_NODE_REF (dst);
771578a0 3318
9771b263 3319 new_info->descriptors = old_info->descriptors.copy ();
310bc633 3320 new_info->lattices = NULL;
771578a0 3321 new_info->ipcp_orig_node = old_info->ipcp_orig_node;
3949c4a7 3322
3949c4a7
MJ
3323 new_info->uses_analysis_done = old_info->uses_analysis_done;
3324 new_info->node_enqueued = old_info->node_enqueued;
2c9561b5
MJ
3325
3326 old_av = ipa_get_agg_replacements_for_node (src);
3327 if (!old_av)
3328 return;
3329
3330 new_av = NULL;
3331 while (old_av)
3332 {
3333 struct ipa_agg_replacement_value *v;
3334
766090c2 3335 v = ggc_alloc<ipa_agg_replacement_value> ();
2c9561b5
MJ
3336 memcpy (v, old_av, sizeof (*v));
3337 v->next = new_av;
3338 new_av = v;
3339 old_av = old_av->next;
3340 }
3341 ipa_set_node_agg_value_chain (dst, new_av);
771578a0
MJ
3342}
3343
40982661
JH
3344
3345/* Analyze newly added function into callgraph. */
3346
3347static void
3348ipa_add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
3349{
0136f8f0
AH
3350 if (cgraph_function_with_gimple_body_p (node))
3351 ipa_analyze_node (node);
40982661
JH
3352}
3353
771578a0 3354/* Register our cgraph hooks if they are not already there. */
be95e2b9 3355
518dc859 3356void
771578a0 3357ipa_register_cgraph_hooks (void)
518dc859 3358{
771578a0
MJ
3359 if (!edge_removal_hook_holder)
3360 edge_removal_hook_holder =
3361 cgraph_add_edge_removal_hook (&ipa_edge_removal_hook, NULL);
3362 if (!node_removal_hook_holder)
3363 node_removal_hook_holder =
3364 cgraph_add_node_removal_hook (&ipa_node_removal_hook, NULL);
3365 if (!edge_duplication_hook_holder)
3366 edge_duplication_hook_holder =
3367 cgraph_add_edge_duplication_hook (&ipa_edge_duplication_hook, NULL);
3368 if (!node_duplication_hook_holder)
3369 node_duplication_hook_holder =
3370 cgraph_add_node_duplication_hook (&ipa_node_duplication_hook, NULL);
40982661
JH
3371 function_insertion_hook_holder =
3372 cgraph_add_function_insertion_hook (&ipa_add_new_function, NULL);
771578a0 3373}
518dc859 3374
771578a0 3375/* Unregister our cgraph hooks if they are not already there. */
be95e2b9 3376
771578a0
MJ
3377static void
3378ipa_unregister_cgraph_hooks (void)
3379{
3380 cgraph_remove_edge_removal_hook (edge_removal_hook_holder);
3381 edge_removal_hook_holder = NULL;
3382 cgraph_remove_node_removal_hook (node_removal_hook_holder);
3383 node_removal_hook_holder = NULL;
3384 cgraph_remove_edge_duplication_hook (edge_duplication_hook_holder);
3385 edge_duplication_hook_holder = NULL;
3386 cgraph_remove_node_duplication_hook (node_duplication_hook_holder);
3387 node_duplication_hook_holder = NULL;
40982661
JH
3388 cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
3389 function_insertion_hook_holder = NULL;
771578a0
MJ
3390}
3391
3392/* Free all ipa_node_params and all ipa_edge_args structures if they are no
3393 longer needed after ipa-cp. */
be95e2b9 3394
771578a0 3395void
e33c6cd6 3396ipa_free_all_structures_after_ipa_cp (void)
3e293154 3397{
5ee53a06 3398 if (!optimize)
3e293154
MJ
3399 {
3400 ipa_free_all_edge_args ();
3401 ipa_free_all_node_params ();
310bc633
MJ
3402 free_alloc_pool (ipcp_sources_pool);
3403 free_alloc_pool (ipcp_values_pool);
2c9561b5 3404 free_alloc_pool (ipcp_agg_lattice_pool);
3e293154 3405 ipa_unregister_cgraph_hooks ();
4502fe8d
MJ
3406 if (ipa_refdesc_pool)
3407 free_alloc_pool (ipa_refdesc_pool);
3e293154
MJ
3408 }
3409}
3410
3411/* Free all ipa_node_params and all ipa_edge_args structures if they are no
3412 longer needed after indirect inlining. */
be95e2b9 3413
3e293154 3414void
e33c6cd6 3415ipa_free_all_structures_after_iinln (void)
771578a0
MJ
3416{
3417 ipa_free_all_edge_args ();
3418 ipa_free_all_node_params ();
3419 ipa_unregister_cgraph_hooks ();
310bc633
MJ
3420 if (ipcp_sources_pool)
3421 free_alloc_pool (ipcp_sources_pool);
3422 if (ipcp_values_pool)
3423 free_alloc_pool (ipcp_values_pool);
2c9561b5
MJ
3424 if (ipcp_agg_lattice_pool)
3425 free_alloc_pool (ipcp_agg_lattice_pool);
4502fe8d
MJ
3426 if (ipa_refdesc_pool)
3427 free_alloc_pool (ipa_refdesc_pool);
518dc859
RL
3428}
3429
dcd416e3 3430/* Print ipa_tree_map data structures of all functions in the
518dc859 3431 callgraph to F. */
be95e2b9 3432
518dc859 3433void
2c9561b5 3434ipa_print_node_params (FILE *f, struct cgraph_node *node)
518dc859
RL
3435{
3436 int i, count;
3e293154 3437 struct ipa_node_params *info;
518dc859 3438
67348ccc 3439 if (!node->definition)
3e293154
MJ
3440 return;
3441 info = IPA_NODE_REF (node);
9de04252 3442 fprintf (f, " function %s/%i parameter descriptors:\n",
fec39fa6 3443 node->name (), node->order);
3e293154
MJ
3444 count = ipa_get_param_count (info);
3445 for (i = 0; i < count; i++)
518dc859 3446 {
4502fe8d
MJ
3447 int c;
3448
a4e33812 3449 fprintf (f, " ");
e067bd43 3450 ipa_dump_param (f, info, i);
339f49ec
JH
3451 if (ipa_is_param_used (info, i))
3452 fprintf (f, " used");
4502fe8d
MJ
3453 c = ipa_get_controlled_uses (info, i);
3454 if (c == IPA_UNDESCRIBED_USE)
3455 fprintf (f, " undescribed_use");
3456 else
3457 fprintf (f, " controlled_uses=%i", c);
3e293154 3458 fprintf (f, "\n");
518dc859
RL
3459 }
3460}
dcd416e3 3461
ca30a539 3462/* Print ipa_tree_map data structures of all functions in the
3e293154 3463 callgraph to F. */
be95e2b9 3464
3e293154 3465void
ca30a539 3466ipa_print_all_params (FILE * f)
3e293154
MJ
3467{
3468 struct cgraph_node *node;
3469
ca30a539 3470 fprintf (f, "\nFunction parameters:\n");
65c70e6b 3471 FOR_EACH_FUNCTION (node)
ca30a539 3472 ipa_print_node_params (f, node);
3e293154 3473}
3f84bf08
MJ
3474
3475/* Return a heap allocated vector containing formal parameters of FNDECL. */
3476
9771b263 3477vec<tree>
3f84bf08
MJ
3478ipa_get_vector_of_formal_parms (tree fndecl)
3479{
9771b263 3480 vec<tree> args;
3f84bf08
MJ
3481 int count;
3482 tree parm;
3483
0e8853ee 3484 gcc_assert (!flag_wpa);
310bc633 3485 count = count_formal_params (fndecl);
9771b263 3486 args.create (count);
910ad8de 3487 for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
9771b263 3488 args.quick_push (parm);
3f84bf08
MJ
3489
3490 return args;
3491}
3492
3493/* Return a heap allocated vector containing types of formal parameters of
3494 function type FNTYPE. */
3495
31519c38
AH
3496vec<tree>
3497ipa_get_vector_of_formal_parm_types (tree fntype)
3f84bf08 3498{
9771b263 3499 vec<tree> types;
3f84bf08
MJ
3500 int count = 0;
3501 tree t;
3502
3503 for (t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t))
3504 count++;
3505
9771b263 3506 types.create (count);
3f84bf08 3507 for (t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t))
9771b263 3508 types.quick_push (TREE_VALUE (t));
3f84bf08
MJ
3509
3510 return types;
3511}
3512
3513/* Modify the function declaration FNDECL and its type according to the plan in
3514 ADJUSTMENTS. It also sets base fields of individual adjustments structures
3515 to reflect the actual parameters being modified which are determined by the
3516 base_index field. */
3517
3518void
31519c38 3519ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments)
3f84bf08 3520{
31519c38
AH
3521 vec<tree> oparms = ipa_get_vector_of_formal_parms (fndecl);
3522 tree orig_type = TREE_TYPE (fndecl);
3523 tree old_arg_types = TYPE_ARG_TYPES (orig_type);
3f84bf08
MJ
3524
3525 /* The following test is an ugly hack, some functions simply don't have any
3526 arguments in their type. This is probably a bug but well... */
31519c38
AH
3527 bool care_for_types = (old_arg_types != NULL_TREE);
3528 bool last_parm_void;
3529 vec<tree> otypes;
3f84bf08
MJ
3530 if (care_for_types)
3531 {
3532 last_parm_void = (TREE_VALUE (tree_last (old_arg_types))
3533 == void_type_node);
31519c38 3534 otypes = ipa_get_vector_of_formal_parm_types (orig_type);
3f84bf08 3535 if (last_parm_void)
9771b263 3536 gcc_assert (oparms.length () + 1 == otypes.length ());
3f84bf08 3537 else
9771b263 3538 gcc_assert (oparms.length () == otypes.length ());
3f84bf08
MJ
3539 }
3540 else
3541 {
3542 last_parm_void = false;
9771b263 3543 otypes.create (0);
3f84bf08
MJ
3544 }
3545
31519c38
AH
3546 int len = adjustments.length ();
3547 tree *link = &DECL_ARGUMENTS (fndecl);
3548 tree new_arg_types = NULL;
3549 for (int i = 0; i < len; i++)
3f84bf08
MJ
3550 {
3551 struct ipa_parm_adjustment *adj;
3552 gcc_assert (link);
3553
9771b263 3554 adj = &adjustments[i];
31519c38
AH
3555 tree parm;
3556 if (adj->op == IPA_PARM_OP_NEW)
3557 parm = NULL;
3558 else
3559 parm = oparms[adj->base_index];
3f84bf08
MJ
3560 adj->base = parm;
3561
31519c38 3562 if (adj->op == IPA_PARM_OP_COPY)
3f84bf08
MJ
3563 {
3564 if (care_for_types)
9771b263 3565 new_arg_types = tree_cons (NULL_TREE, otypes[adj->base_index],
3f84bf08
MJ
3566 new_arg_types);
3567 *link = parm;
910ad8de 3568 link = &DECL_CHAIN (parm);
3f84bf08 3569 }
31519c38 3570 else if (adj->op != IPA_PARM_OP_REMOVE)
3f84bf08
MJ
3571 {
3572 tree new_parm;
3573 tree ptype;
3574
3575 if (adj->by_ref)
3576 ptype = build_pointer_type (adj->type);
3577 else
e69dbe37
MJ
3578 {
3579 ptype = adj->type;
3580 if (is_gimple_reg_type (ptype))
3581 {
3582 unsigned malign = GET_MODE_ALIGNMENT (TYPE_MODE (ptype));
3583 if (TYPE_ALIGN (ptype) < malign)
3584 ptype = build_aligned_type (ptype, malign);
3585 }
3586 }
3f84bf08
MJ
3587
3588 if (care_for_types)
3589 new_arg_types = tree_cons (NULL_TREE, ptype, new_arg_types);
3590
3591 new_parm = build_decl (UNKNOWN_LOCATION, PARM_DECL, NULL_TREE,
3592 ptype);
31519c38
AH
3593 const char *prefix = adj->arg_prefix ? adj->arg_prefix : "SYNTH";
3594 DECL_NAME (new_parm) = create_tmp_var_name (prefix);
3f84bf08
MJ
3595 DECL_ARTIFICIAL (new_parm) = 1;
3596 DECL_ARG_TYPE (new_parm) = ptype;
3597 DECL_CONTEXT (new_parm) = fndecl;
3598 TREE_USED (new_parm) = 1;
3599 DECL_IGNORED_P (new_parm) = 1;
3600 layout_decl (new_parm, 0);
3601
31519c38
AH
3602 if (adj->op == IPA_PARM_OP_NEW)
3603 adj->base = NULL;
3604 else
3605 adj->base = parm;
3606 adj->new_decl = new_parm;
3f84bf08
MJ
3607
3608 *link = new_parm;
910ad8de 3609 link = &DECL_CHAIN (new_parm);
3f84bf08
MJ
3610 }
3611 }
3612
3613 *link = NULL_TREE;
3614
31519c38 3615 tree new_reversed = NULL;
3f84bf08
MJ
3616 if (care_for_types)
3617 {
3618 new_reversed = nreverse (new_arg_types);
3619 if (last_parm_void)
3620 {
3621 if (new_reversed)
3622 TREE_CHAIN (new_arg_types) = void_list_node;
3623 else
3624 new_reversed = void_list_node;
3625 }
3626 }
3627
3628 /* Use copy_node to preserve as much as possible from original type
3629 (debug info, attribute lists etc.)
3630 Exception is METHOD_TYPEs must have THIS argument.
3631 When we are asked to remove it, we need to build new FUNCTION_TYPE
3632 instead. */
31519c38 3633 tree new_type = NULL;
3f84bf08 3634 if (TREE_CODE (orig_type) != METHOD_TYPE
31519c38 3635 || (adjustments[0].op == IPA_PARM_OP_COPY
9771b263 3636 && adjustments[0].base_index == 0))
3f84bf08 3637 {
4eb3f32c 3638 new_type = build_distinct_type_copy (orig_type);
3f84bf08
MJ
3639 TYPE_ARG_TYPES (new_type) = new_reversed;
3640 }
3641 else
3642 {
3643 new_type
3644 = build_distinct_type_copy (build_function_type (TREE_TYPE (orig_type),
3645 new_reversed));
3646 TYPE_CONTEXT (new_type) = TYPE_CONTEXT (orig_type);
3647 DECL_VINDEX (fndecl) = NULL_TREE;
3648 }
3649
d402c33d
JH
3650 /* When signature changes, we need to clear builtin info. */
3651 if (DECL_BUILT_IN (fndecl))
3652 {
3653 DECL_BUILT_IN_CLASS (fndecl) = NOT_BUILT_IN;
3654 DECL_FUNCTION_CODE (fndecl) = (enum built_in_function) 0;
3655 }
3656
3f84bf08
MJ
3657 /* This is a new type, not a copy of an old type. Need to reassociate
3658 variants. We can handle everything except the main variant lazily. */
31519c38 3659 tree t = TYPE_MAIN_VARIANT (orig_type);
3f84bf08
MJ
3660 if (orig_type != t)
3661 {
3662 TYPE_MAIN_VARIANT (new_type) = t;
3663 TYPE_NEXT_VARIANT (new_type) = TYPE_NEXT_VARIANT (t);
3664 TYPE_NEXT_VARIANT (t) = new_type;
3665 }
3666 else
3667 {
3668 TYPE_MAIN_VARIANT (new_type) = new_type;
3669 TYPE_NEXT_VARIANT (new_type) = NULL;
3670 }
3671
3672 TREE_TYPE (fndecl) = new_type;
9b389a5e 3673 DECL_VIRTUAL_P (fndecl) = 0;
70d6d5c1 3674 DECL_LANG_SPECIFIC (fndecl) = NULL;
9771b263
DN
3675 otypes.release ();
3676 oparms.release ();
3f84bf08
MJ
3677}
3678
3679/* Modify actual arguments of a function call CS as indicated in ADJUSTMENTS.
3680 If this is a directly recursive call, CS must be NULL. Otherwise it must
3681 contain the corresponding call graph edge. */
3682
3683void
3684ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
3685 ipa_parm_adjustment_vec adjustments)
3686{
82338059 3687 struct cgraph_node *current_node = cgraph_get_node (current_function_decl);
9771b263
DN
3688 vec<tree> vargs;
3689 vec<tree, va_gc> **debug_args = NULL;
3f84bf08 3690 gimple new_stmt;
82338059 3691 gimple_stmt_iterator gsi, prev_gsi;
3f84bf08
MJ
3692 tree callee_decl;
3693 int i, len;
3694
9771b263
DN
3695 len = adjustments.length ();
3696 vargs.create (len);
67348ccc
DM
3697 callee_decl = !cs ? gimple_call_fndecl (stmt) : cs->callee->decl;
3698 ipa_remove_stmt_references (current_node, stmt);
3f84bf08
MJ
3699
3700 gsi = gsi_for_stmt (stmt);
82338059
MJ
3701 prev_gsi = gsi;
3702 gsi_prev (&prev_gsi);
3f84bf08
MJ
3703 for (i = 0; i < len; i++)
3704 {
3705 struct ipa_parm_adjustment *adj;
3706
9771b263 3707 adj = &adjustments[i];
3f84bf08 3708
31519c38 3709 if (adj->op == IPA_PARM_OP_COPY)
3f84bf08
MJ
3710 {
3711 tree arg = gimple_call_arg (stmt, adj->base_index);
3712
9771b263 3713 vargs.quick_push (arg);
3f84bf08 3714 }
31519c38 3715 else if (adj->op != IPA_PARM_OP_REMOVE)
3f84bf08 3716 {
fffe1e40
MJ
3717 tree expr, base, off;
3718 location_t loc;
f43245d1 3719 unsigned int deref_align = 0;
c1ed6a01 3720 bool deref_base = false;
fffe1e40
MJ
3721
3722 /* We create a new parameter out of the value of the old one, we can
3723 do the following kind of transformations:
3724
3725 - A scalar passed by reference is converted to a scalar passed by
3726 value. (adj->by_ref is false and the type of the original
3727 actual argument is a pointer to a scalar).
3728
3729 - A part of an aggregate is passed instead of the whole aggregate.
3730 The part can be passed either by value or by reference, this is
3731 determined by value of adj->by_ref. Moreover, the code below
3732 handles both situations when the original aggregate is passed by
3733 value (its type is not a pointer) and when it is passed by
3734 reference (it is a pointer to an aggregate).
3735
3736 When the new argument is passed by reference (adj->by_ref is true)
3737 it must be a part of an aggregate and therefore we form it by
3738 simply taking the address of a reference inside the original
3739 aggregate. */
3740
3741 gcc_checking_assert (adj->offset % BITS_PER_UNIT == 0);
3742 base = gimple_call_arg (stmt, adj->base_index);
3a50da34
DC
3743 loc = DECL_P (base) ? DECL_SOURCE_LOCATION (base)
3744 : EXPR_LOCATION (base);
fffe1e40 3745
82d49829
MJ
3746 if (TREE_CODE (base) != ADDR_EXPR
3747 && POINTER_TYPE_P (TREE_TYPE (base)))
3748 off = build_int_cst (adj->alias_ptr_type,
fffe1e40 3749 adj->offset / BITS_PER_UNIT);
3f84bf08 3750 else
3f84bf08 3751 {
fffe1e40
MJ
3752 HOST_WIDE_INT base_offset;
3753 tree prev_base;
c1ed6a01 3754 bool addrof;
fffe1e40
MJ
3755
3756 if (TREE_CODE (base) == ADDR_EXPR)
c1ed6a01
MJ
3757 {
3758 base = TREE_OPERAND (base, 0);
3759 addrof = true;
3760 }
3761 else
3762 addrof = false;
fffe1e40
MJ
3763 prev_base = base;
3764 base = get_addr_base_and_unit_offset (base, &base_offset);
3765 /* Aggregate arguments can have non-invariant addresses. */
3766 if (!base)
3767 {
3768 base = build_fold_addr_expr (prev_base);
82d49829 3769 off = build_int_cst (adj->alias_ptr_type,
fffe1e40
MJ
3770 adj->offset / BITS_PER_UNIT);
3771 }
3772 else if (TREE_CODE (base) == MEM_REF)
3773 {
c1ed6a01
MJ
3774 if (!addrof)
3775 {
3776 deref_base = true;
3777 deref_align = TYPE_ALIGN (TREE_TYPE (base));
3778 }
82d49829 3779 off = build_int_cst (adj->alias_ptr_type,
fffe1e40
MJ
3780 base_offset
3781 + adj->offset / BITS_PER_UNIT);
3782 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1),
d35936ab 3783 off);
fffe1e40
MJ
3784 base = TREE_OPERAND (base, 0);
3785 }
3786 else
3787 {
82d49829 3788 off = build_int_cst (adj->alias_ptr_type,
fffe1e40
MJ
3789 base_offset
3790 + adj->offset / BITS_PER_UNIT);
3791 base = build_fold_addr_expr (base);
3792 }
3f84bf08 3793 }
fffe1e40 3794
3a5a825a
RG
3795 if (!adj->by_ref)
3796 {
3797 tree type = adj->type;
3798 unsigned int align;
3799 unsigned HOST_WIDE_INT misalign;
644ffefd 3800
c1ed6a01
MJ
3801 if (deref_base)
3802 {
3803 align = deref_align;
3804 misalign = 0;
3805 }
3806 else
3807 {
3808 get_pointer_alignment_1 (base, &align, &misalign);
3809 if (TYPE_ALIGN (type) > align)
3810 align = TYPE_ALIGN (type);
3811 }
807e902e 3812 misalign += (offset_int::from (off, SIGNED).to_short_addr ()
3a5a825a
RG
3813 * BITS_PER_UNIT);
3814 misalign = misalign & (align - 1);
3815 if (misalign != 0)
3816 align = (misalign & -misalign);
3817 if (align < TYPE_ALIGN (type))
3818 type = build_aligned_type (type, align);
4df65a85
RB
3819 base = force_gimple_operand_gsi (&gsi, base,
3820 true, NULL, true, GSI_SAME_STMT);
3a5a825a 3821 expr = fold_build2_loc (loc, MEM_REF, type, base, off);
4df65a85
RB
3822 /* If expr is not a valid gimple call argument emit
3823 a load into a temporary. */
3824 if (is_gimple_reg_type (TREE_TYPE (expr)))
3825 {
3826 gimple tem = gimple_build_assign (NULL_TREE, expr);
3827 if (gimple_in_ssa_p (cfun))
3828 {
3829 gimple_set_vuse (tem, gimple_vuse (stmt));
3830 expr = make_ssa_name (TREE_TYPE (expr), tem);
3831 }
3832 else
3833 expr = create_tmp_reg (TREE_TYPE (expr), NULL);
3834 gimple_assign_set_lhs (tem, expr);
3835 gsi_insert_before (&gsi, tem, GSI_SAME_STMT);
3836 }
3a5a825a
RG
3837 }
3838 else
3839 {
3840 expr = fold_build2_loc (loc, MEM_REF, adj->type, base, off);
3841 expr = build_fold_addr_expr (expr);
4df65a85
RB
3842 expr = force_gimple_operand_gsi (&gsi, expr,
3843 true, NULL, true, GSI_SAME_STMT);
3a5a825a 3844 }
9771b263 3845 vargs.quick_push (expr);
3f84bf08 3846 }
31519c38 3847 if (adj->op != IPA_PARM_OP_COPY && MAY_HAVE_DEBUG_STMTS)
ddb555ed
JJ
3848 {
3849 unsigned int ix;
3850 tree ddecl = NULL_TREE, origin = DECL_ORIGIN (adj->base), arg;
3851 gimple def_temp;
3852
3853 arg = gimple_call_arg (stmt, adj->base_index);
3854 if (!useless_type_conversion_p (TREE_TYPE (origin), TREE_TYPE (arg)))
3855 {
3856 if (!fold_convertible_p (TREE_TYPE (origin), arg))
3857 continue;
3858 arg = fold_convert_loc (gimple_location (stmt),
3859 TREE_TYPE (origin), arg);
3860 }
3861 if (debug_args == NULL)
3862 debug_args = decl_debug_args_insert (callee_decl);
9771b263 3863 for (ix = 0; vec_safe_iterate (*debug_args, ix, &ddecl); ix += 2)
ddb555ed
JJ
3864 if (ddecl == origin)
3865 {
9771b263 3866 ddecl = (**debug_args)[ix + 1];
ddb555ed
JJ
3867 break;
3868 }
3869 if (ddecl == NULL)
3870 {
3871 ddecl = make_node (DEBUG_EXPR_DECL);
3872 DECL_ARTIFICIAL (ddecl) = 1;
3873 TREE_TYPE (ddecl) = TREE_TYPE (origin);
3874 DECL_MODE (ddecl) = DECL_MODE (origin);
3875
9771b263
DN
3876 vec_safe_push (*debug_args, origin);
3877 vec_safe_push (*debug_args, ddecl);
ddb555ed 3878 }
9771b263 3879 def_temp = gimple_build_debug_bind (ddecl, unshare_expr (arg), stmt);
ddb555ed
JJ
3880 gsi_insert_before (&gsi, def_temp, GSI_SAME_STMT);
3881 }
3f84bf08
MJ
3882 }
3883
3884 if (dump_file && (dump_flags & TDF_DETAILS))
3885 {
3886 fprintf (dump_file, "replacing stmt:");
3887 print_gimple_stmt (dump_file, gsi_stmt (gsi), 0, 0);
3888 }
3889
3f84bf08 3890 new_stmt = gimple_build_call_vec (callee_decl, vargs);
9771b263 3891 vargs.release ();
3f84bf08
MJ
3892 if (gimple_call_lhs (stmt))
3893 gimple_call_set_lhs (new_stmt, gimple_call_lhs (stmt));
3894
3895 gimple_set_block (new_stmt, gimple_block (stmt));
3896 if (gimple_has_location (stmt))
3897 gimple_set_location (new_stmt, gimple_location (stmt));
3f84bf08 3898 gimple_call_set_chain (new_stmt, gimple_call_chain (stmt));
a7a296ab 3899 gimple_call_copy_flags (new_stmt, stmt);
4df65a85
RB
3900 if (gimple_in_ssa_p (cfun))
3901 {
3902 gimple_set_vuse (new_stmt, gimple_vuse (stmt));
3903 if (gimple_vdef (stmt))
3904 {
3905 gimple_set_vdef (new_stmt, gimple_vdef (stmt));
3906 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
3907 }
3908 }
3f84bf08
MJ
3909
3910 if (dump_file && (dump_flags & TDF_DETAILS))
3911 {
3912 fprintf (dump_file, "with stmt:");
3913 print_gimple_stmt (dump_file, new_stmt, 0, 0);
3914 fprintf (dump_file, "\n");
3915 }
3916 gsi_replace (&gsi, new_stmt, true);
3917 if (cs)
3918 cgraph_set_call_stmt (cs, new_stmt);
82338059
MJ
3919 do
3920 {
3921 ipa_record_stmt_references (current_node, gsi_stmt (gsi));
3922 gsi_prev (&gsi);
3923 }
3d354792 3924 while (gsi_stmt (gsi) != gsi_stmt (prev_gsi));
3f84bf08
MJ
3925}
3926
31519c38
AH
3927/* If the expression *EXPR should be replaced by a reduction of a parameter, do
3928 so. ADJUSTMENTS is a pointer to a vector of adjustments. CONVERT
3929 specifies whether the function should care about type incompatibility the
3930 current and new expressions. If it is false, the function will leave
3931 incompatibility issues to the caller. Return true iff the expression
3932 was modified. */
3933
3934bool
3935ipa_modify_expr (tree *expr, bool convert,
3936 ipa_parm_adjustment_vec adjustments)
3937{
3938 struct ipa_parm_adjustment *cand
3939 = ipa_get_adjustment_candidate (&expr, &convert, adjustments, false);
3940 if (!cand)
3941 return false;
3942
3943 tree src;
3944 if (cand->by_ref)
3945 src = build_simple_mem_ref (cand->new_decl);
3946 else
3947 src = cand->new_decl;
3948
3949 if (dump_file && (dump_flags & TDF_DETAILS))
3950 {
3951 fprintf (dump_file, "About to replace expr ");
3952 print_generic_expr (dump_file, *expr, 0);
3953 fprintf (dump_file, " with ");
3954 print_generic_expr (dump_file, src, 0);
3955 fprintf (dump_file, "\n");
3956 }
3957
3958 if (convert && !useless_type_conversion_p (TREE_TYPE (*expr), cand->type))
3959 {
3960 tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*expr), src);
3961 *expr = vce;
3962 }
3963 else
3964 *expr = src;
3965 return true;
3966}
3967
3968/* If T is an SSA_NAME, return NULL if it is not a default def or
3969 return its base variable if it is. If IGNORE_DEFAULT_DEF is true,
3970 the base variable is always returned, regardless if it is a default
3971 def. Return T if it is not an SSA_NAME. */
3972
3973static tree
3974get_ssa_base_param (tree t, bool ignore_default_def)
3975{
3976 if (TREE_CODE (t) == SSA_NAME)
3977 {
3978 if (ignore_default_def || SSA_NAME_IS_DEFAULT_DEF (t))
3979 return SSA_NAME_VAR (t);
3980 else
3981 return NULL_TREE;
3982 }
3983 return t;
3984}
3985
3986/* Given an expression, return an adjustment entry specifying the
3987 transformation to be done on EXPR. If no suitable adjustment entry
3988 was found, returns NULL.
3989
3990 If IGNORE_DEFAULT_DEF is set, consider SSA_NAMEs which are not a
3991 default def, otherwise bail on them.
3992
3993 If CONVERT is non-NULL, this function will set *CONVERT if the
3994 expression provided is a component reference. ADJUSTMENTS is the
3995 adjustments vector. */
3996
3997ipa_parm_adjustment *
3998ipa_get_adjustment_candidate (tree **expr, bool *convert,
3999 ipa_parm_adjustment_vec adjustments,
4000 bool ignore_default_def)
4001{
4002 if (TREE_CODE (**expr) == BIT_FIELD_REF
4003 || TREE_CODE (**expr) == IMAGPART_EXPR
4004 || TREE_CODE (**expr) == REALPART_EXPR)
4005 {
4006 *expr = &TREE_OPERAND (**expr, 0);
4007 if (convert)
4008 *convert = true;
4009 }
4010
4011 HOST_WIDE_INT offset, size, max_size;
4012 tree base = get_ref_base_and_extent (**expr, &offset, &size, &max_size);
4013 if (!base || size == -1 || max_size == -1)
4014 return NULL;
4015
4016 if (TREE_CODE (base) == MEM_REF)
4017 {
807e902e 4018 offset += mem_ref_offset (base).to_short_addr () * BITS_PER_UNIT;
31519c38
AH
4019 base = TREE_OPERAND (base, 0);
4020 }
4021
4022 base = get_ssa_base_param (base, ignore_default_def);
4023 if (!base || TREE_CODE (base) != PARM_DECL)
4024 return NULL;
4025
4026 struct ipa_parm_adjustment *cand = NULL;
4027 unsigned int len = adjustments.length ();
4028 for (unsigned i = 0; i < len; i++)
4029 {
4030 struct ipa_parm_adjustment *adj = &adjustments[i];
4031
4032 if (adj->base == base
4033 && (adj->offset == offset || adj->op == IPA_PARM_OP_REMOVE))
4034 {
4035 cand = adj;
4036 break;
4037 }
4038 }
4039
4040 if (!cand || cand->op == IPA_PARM_OP_COPY || cand->op == IPA_PARM_OP_REMOVE)
4041 return NULL;
4042 return cand;
4043}
4044
3f84bf08
MJ
4045/* Return true iff BASE_INDEX is in ADJUSTMENTS more than once. */
4046
4047static bool
4048index_in_adjustments_multiple_times_p (int base_index,
4049 ipa_parm_adjustment_vec adjustments)
4050{
9771b263 4051 int i, len = adjustments.length ();
3f84bf08
MJ
4052 bool one = false;
4053
4054 for (i = 0; i < len; i++)
4055 {
4056 struct ipa_parm_adjustment *adj;
9771b263 4057 adj = &adjustments[i];
3f84bf08
MJ
4058
4059 if (adj->base_index == base_index)
4060 {
4061 if (one)
4062 return true;
4063 else
4064 one = true;
4065 }
4066 }
4067 return false;
4068}
4069
4070
4071/* Return adjustments that should have the same effect on function parameters
4072 and call arguments as if they were first changed according to adjustments in
4073 INNER and then by adjustments in OUTER. */
4074
4075ipa_parm_adjustment_vec
4076ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
4077 ipa_parm_adjustment_vec outer)
4078{
9771b263
DN
4079 int i, outlen = outer.length ();
4080 int inlen = inner.length ();
3f84bf08
MJ
4081 int removals = 0;
4082 ipa_parm_adjustment_vec adjustments, tmp;
4083
9771b263 4084 tmp.create (inlen);
3f84bf08
MJ
4085 for (i = 0; i < inlen; i++)
4086 {
4087 struct ipa_parm_adjustment *n;
9771b263 4088 n = &inner[i];
3f84bf08 4089
31519c38 4090 if (n->op == IPA_PARM_OP_REMOVE)
3f84bf08
MJ
4091 removals++;
4092 else
31519c38
AH
4093 {
4094 /* FIXME: Handling of new arguments are not implemented yet. */
4095 gcc_assert (n->op != IPA_PARM_OP_NEW);
4096 tmp.quick_push (*n);
4097 }
3f84bf08
MJ
4098 }
4099
9771b263 4100 adjustments.create (outlen + removals);
3f84bf08
MJ
4101 for (i = 0; i < outlen; i++)
4102 {
f32682ca 4103 struct ipa_parm_adjustment r;
9771b263
DN
4104 struct ipa_parm_adjustment *out = &outer[i];
4105 struct ipa_parm_adjustment *in = &tmp[out->base_index];
3f84bf08 4106
f32682ca 4107 memset (&r, 0, sizeof (r));
31519c38
AH
4108 gcc_assert (in->op != IPA_PARM_OP_REMOVE);
4109 if (out->op == IPA_PARM_OP_REMOVE)
3f84bf08
MJ
4110 {
4111 if (!index_in_adjustments_multiple_times_p (in->base_index, tmp))
4112 {
31519c38 4113 r.op = IPA_PARM_OP_REMOVE;
9771b263 4114 adjustments.quick_push (r);
3f84bf08
MJ
4115 }
4116 continue;
4117 }
31519c38
AH
4118 else
4119 {
4120 /* FIXME: Handling of new arguments are not implemented yet. */
4121 gcc_assert (out->op != IPA_PARM_OP_NEW);
4122 }
3f84bf08 4123
f32682ca
DN
4124 r.base_index = in->base_index;
4125 r.type = out->type;
3f84bf08
MJ
4126
4127 /* FIXME: Create nonlocal value too. */
4128
31519c38
AH
4129 if (in->op == IPA_PARM_OP_COPY && out->op == IPA_PARM_OP_COPY)
4130 r.op = IPA_PARM_OP_COPY;
4131 else if (in->op == IPA_PARM_OP_COPY)
f32682ca 4132 r.offset = out->offset;
31519c38 4133 else if (out->op == IPA_PARM_OP_COPY)
f32682ca 4134 r.offset = in->offset;
3f84bf08 4135 else
f32682ca 4136 r.offset = in->offset + out->offset;
9771b263 4137 adjustments.quick_push (r);
3f84bf08
MJ
4138 }
4139
4140 for (i = 0; i < inlen; i++)
4141 {
9771b263 4142 struct ipa_parm_adjustment *n = &inner[i];
3f84bf08 4143
31519c38 4144 if (n->op == IPA_PARM_OP_REMOVE)
9771b263 4145 adjustments.quick_push (*n);
3f84bf08
MJ
4146 }
4147
9771b263 4148 tmp.release ();
3f84bf08
MJ
4149 return adjustments;
4150}
4151
4152/* Dump the adjustments in the vector ADJUSTMENTS to dump_file in a human
4153 friendly way, assuming they are meant to be applied to FNDECL. */
4154
4155void
4156ipa_dump_param_adjustments (FILE *file, ipa_parm_adjustment_vec adjustments,
4157 tree fndecl)
4158{
9771b263 4159 int i, len = adjustments.length ();
3f84bf08 4160 bool first = true;
9771b263 4161 vec<tree> parms = ipa_get_vector_of_formal_parms (fndecl);
3f84bf08
MJ
4162
4163 fprintf (file, "IPA param adjustments: ");
4164 for (i = 0; i < len; i++)
4165 {
4166 struct ipa_parm_adjustment *adj;
9771b263 4167 adj = &adjustments[i];
3f84bf08
MJ
4168
4169 if (!first)
4170 fprintf (file, " ");
4171 else
4172 first = false;
4173
4174 fprintf (file, "%i. base_index: %i - ", i, adj->base_index);
9771b263 4175 print_generic_expr (file, parms[adj->base_index], 0);
3f84bf08
MJ
4176 if (adj->base)
4177 {
4178 fprintf (file, ", base: ");
4179 print_generic_expr (file, adj->base, 0);
4180 }
31519c38 4181 if (adj->new_decl)
3f84bf08 4182 {
31519c38
AH
4183 fprintf (file, ", new_decl: ");
4184 print_generic_expr (file, adj->new_decl, 0);
3f84bf08
MJ
4185 }
4186 if (adj->new_ssa_base)
4187 {
4188 fprintf (file, ", new_ssa_base: ");
4189 print_generic_expr (file, adj->new_ssa_base, 0);
4190 }
4191
31519c38 4192 if (adj->op == IPA_PARM_OP_COPY)
3f84bf08 4193 fprintf (file, ", copy_param");
31519c38 4194 else if (adj->op == IPA_PARM_OP_REMOVE)
3f84bf08
MJ
4195 fprintf (file, ", remove_param");
4196 else
4197 fprintf (file, ", offset %li", (long) adj->offset);
4198 if (adj->by_ref)
4199 fprintf (file, ", by_ref");
4200 print_node_brief (file, ", type: ", adj->type, 0);
4201 fprintf (file, "\n");
4202 }
9771b263 4203 parms.release ();
3f84bf08
MJ
4204}
4205
2c9561b5
MJ
4206/* Dump the AV linked list. */
4207
4208void
4209ipa_dump_agg_replacement_values (FILE *f, struct ipa_agg_replacement_value *av)
4210{
4211 bool comma = false;
4212 fprintf (f, " Aggregate replacements:");
4213 for (; av; av = av->next)
4214 {
4215 fprintf (f, "%s %i[" HOST_WIDE_INT_PRINT_DEC "]=", comma ? "," : "",
4216 av->index, av->offset);
4217 print_generic_expr (f, av->value, 0);
4218 comma = true;
4219 }
4220 fprintf (f, "\n");
4221}
4222
fb3f88cc
JH
4223/* Stream out jump function JUMP_FUNC to OB. */
4224
4225static void
4226ipa_write_jump_function (struct output_block *ob,
4227 struct ipa_jump_func *jump_func)
4228{
8b7773a4
MJ
4229 struct ipa_agg_jf_item *item;
4230 struct bitpack_d bp;
4231 int i, count;
fb3f88cc 4232
8b7773a4 4233 streamer_write_uhwi (ob, jump_func->type);
fb3f88cc
JH
4234 switch (jump_func->type)
4235 {
4236 case IPA_JF_UNKNOWN:
4237 break;
b258210c 4238 case IPA_JF_KNOWN_TYPE:
c7573249
MJ
4239 streamer_write_uhwi (ob, jump_func->value.known_type.offset);
4240 stream_write_tree (ob, jump_func->value.known_type.base_type, true);
4241 stream_write_tree (ob, jump_func->value.known_type.component_type, true);
b258210c 4242 break;
fb3f88cc 4243 case IPA_JF_CONST:
5368224f 4244 gcc_assert (
4502fe8d
MJ
4245 EXPR_LOCATION (jump_func->value.constant.value) == UNKNOWN_LOCATION);
4246 stream_write_tree (ob, jump_func->value.constant.value, true);
fb3f88cc
JH
4247 break;
4248 case IPA_JF_PASS_THROUGH:
412288f1 4249 streamer_write_uhwi (ob, jump_func->value.pass_through.operation);
4a53743e
MJ
4250 if (jump_func->value.pass_through.operation == NOP_EXPR)
4251 {
4252 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4253 bp = bitpack_create (ob->main_stream);
4254 bp_pack_value (&bp, jump_func->value.pass_through.agg_preserved, 1);
b8f6e610 4255 bp_pack_value (&bp, jump_func->value.pass_through.type_preserved, 1);
4a53743e
MJ
4256 streamer_write_bitpack (&bp);
4257 }
4258 else
4259 {
4260 stream_write_tree (ob, jump_func->value.pass_through.operand, true);
4261 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4262 }
fb3f88cc
JH
4263 break;
4264 case IPA_JF_ANCESTOR:
412288f1 4265 streamer_write_uhwi (ob, jump_func->value.ancestor.offset);
b9393656 4266 stream_write_tree (ob, jump_func->value.ancestor.type, true);
412288f1 4267 streamer_write_uhwi (ob, jump_func->value.ancestor.formal_id);
8b7773a4
MJ
4268 bp = bitpack_create (ob->main_stream);
4269 bp_pack_value (&bp, jump_func->value.ancestor.agg_preserved, 1);
b8f6e610 4270 bp_pack_value (&bp, jump_func->value.ancestor.type_preserved, 1);
8b7773a4 4271 streamer_write_bitpack (&bp);
fb3f88cc 4272 break;
8b7773a4
MJ
4273 }
4274
9771b263 4275 count = vec_safe_length (jump_func->agg.items);
8b7773a4
MJ
4276 streamer_write_uhwi (ob, count);
4277 if (count)
4278 {
4279 bp = bitpack_create (ob->main_stream);
4280 bp_pack_value (&bp, jump_func->agg.by_ref, 1);
4281 streamer_write_bitpack (&bp);
4282 }
4283
9771b263 4284 FOR_EACH_VEC_SAFE_ELT (jump_func->agg.items, i, item)
8b7773a4
MJ
4285 {
4286 streamer_write_uhwi (ob, item->offset);
4287 stream_write_tree (ob, item->value, true);
fb3f88cc
JH
4288 }
4289}
4290
4291/* Read in jump function JUMP_FUNC from IB. */
4292
4293static void
4294ipa_read_jump_function (struct lto_input_block *ib,
4295 struct ipa_jump_func *jump_func,
4502fe8d 4296 struct cgraph_edge *cs,
fb3f88cc
JH
4297 struct data_in *data_in)
4298{
4a53743e
MJ
4299 enum jump_func_type jftype;
4300 enum tree_code operation;
8b7773a4 4301 int i, count;
fb3f88cc 4302
4a53743e
MJ
4303 jftype = (enum jump_func_type) streamer_read_uhwi (ib);
4304 switch (jftype)
fb3f88cc
JH
4305 {
4306 case IPA_JF_UNKNOWN:
4a53743e 4307 jump_func->type = IPA_JF_UNKNOWN;
fb3f88cc 4308 break;
b258210c 4309 case IPA_JF_KNOWN_TYPE:
4a53743e
MJ
4310 {
4311 HOST_WIDE_INT offset = streamer_read_uhwi (ib);
4312 tree base_type = stream_read_tree (ib, data_in);
4313 tree component_type = stream_read_tree (ib, data_in);
4314
4315 ipa_set_jf_known_type (jump_func, offset, base_type, component_type);
4316 break;
4317 }
fb3f88cc 4318 case IPA_JF_CONST:
4502fe8d 4319 ipa_set_jf_constant (jump_func, stream_read_tree (ib, data_in), cs);
fb3f88cc
JH
4320 break;
4321 case IPA_JF_PASS_THROUGH:
4a53743e
MJ
4322 operation = (enum tree_code) streamer_read_uhwi (ib);
4323 if (operation == NOP_EXPR)
4324 {
4325 int formal_id = streamer_read_uhwi (ib);
4326 struct bitpack_d bp = streamer_read_bitpack (ib);
4327 bool agg_preserved = bp_unpack_value (&bp, 1);
b8f6e610
MJ
4328 bool type_preserved = bp_unpack_value (&bp, 1);
4329 ipa_set_jf_simple_pass_through (jump_func, formal_id, agg_preserved,
4330 type_preserved);
4a53743e
MJ
4331 }
4332 else
4333 {
4334 tree operand = stream_read_tree (ib, data_in);
4335 int formal_id = streamer_read_uhwi (ib);
4336 ipa_set_jf_arith_pass_through (jump_func, formal_id, operand,
4337 operation);
4338 }
fb3f88cc
JH
4339 break;
4340 case IPA_JF_ANCESTOR:
4a53743e
MJ
4341 {
4342 HOST_WIDE_INT offset = streamer_read_uhwi (ib);
4343 tree type = stream_read_tree (ib, data_in);
4344 int formal_id = streamer_read_uhwi (ib);
4345 struct bitpack_d bp = streamer_read_bitpack (ib);
4346 bool agg_preserved = bp_unpack_value (&bp, 1);
b8f6e610 4347 bool type_preserved = bp_unpack_value (&bp, 1);
4a53743e 4348
b8f6e610
MJ
4349 ipa_set_ancestor_jf (jump_func, offset, type, formal_id, agg_preserved,
4350 type_preserved);
4a53743e
MJ
4351 break;
4352 }
8b7773a4
MJ
4353 }
4354
4355 count = streamer_read_uhwi (ib);
9771b263 4356 vec_alloc (jump_func->agg.items, count);
8b7773a4
MJ
4357 if (count)
4358 {
4a53743e 4359 struct bitpack_d bp = streamer_read_bitpack (ib);
8b7773a4
MJ
4360 jump_func->agg.by_ref = bp_unpack_value (&bp, 1);
4361 }
4362 for (i = 0; i < count; i++)
4363 {
f32682ca
DN
4364 struct ipa_agg_jf_item item;
4365 item.offset = streamer_read_uhwi (ib);
4366 item.value = stream_read_tree (ib, data_in);
9771b263 4367 jump_func->agg.items->quick_push (item);
fb3f88cc
JH
4368 }
4369}
4370
e33c6cd6
MJ
4371/* Stream out parts of cgraph_indirect_call_info corresponding to CS that are
4372 relevant to indirect inlining to OB. */
661e7330
MJ
4373
4374static void
e33c6cd6
MJ
4375ipa_write_indirect_edge_info (struct output_block *ob,
4376 struct cgraph_edge *cs)
661e7330 4377{
e33c6cd6 4378 struct cgraph_indirect_call_info *ii = cs->indirect_info;
2465dcc2 4379 struct bitpack_d bp;
e33c6cd6 4380
412288f1 4381 streamer_write_hwi (ob, ii->param_index);
8b7773a4 4382 streamer_write_hwi (ob, ii->offset);
2465dcc2
RG
4383 bp = bitpack_create (ob->main_stream);
4384 bp_pack_value (&bp, ii->polymorphic, 1);
8b7773a4 4385 bp_pack_value (&bp, ii->agg_contents, 1);
c13bc3d9 4386 bp_pack_value (&bp, ii->member_ptr, 1);
8b7773a4 4387 bp_pack_value (&bp, ii->by_ref, 1);
68377e53
JH
4388 bp_pack_value (&bp, ii->maybe_in_construction, 1);
4389 bp_pack_value (&bp, ii->maybe_derived_type, 1);
412288f1 4390 streamer_write_bitpack (&bp);
b258210c
MJ
4391
4392 if (ii->polymorphic)
4393 {
412288f1 4394 streamer_write_hwi (ob, ii->otr_token);
b9393656 4395 stream_write_tree (ob, ii->otr_type, true);
68377e53 4396 stream_write_tree (ob, ii->outer_type, true);
b258210c 4397 }
661e7330
MJ
4398}
4399
e33c6cd6
MJ
4400/* Read in parts of cgraph_indirect_call_info corresponding to CS that are
4401 relevant to indirect inlining from IB. */
661e7330
MJ
4402
4403static void
e33c6cd6
MJ
4404ipa_read_indirect_edge_info (struct lto_input_block *ib,
4405 struct data_in *data_in ATTRIBUTE_UNUSED,
4406 struct cgraph_edge *cs)
661e7330 4407{
e33c6cd6 4408 struct cgraph_indirect_call_info *ii = cs->indirect_info;
2465dcc2 4409 struct bitpack_d bp;
661e7330 4410
412288f1 4411 ii->param_index = (int) streamer_read_hwi (ib);
8b7773a4 4412 ii->offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
412288f1 4413 bp = streamer_read_bitpack (ib);
2465dcc2 4414 ii->polymorphic = bp_unpack_value (&bp, 1);
8b7773a4 4415 ii->agg_contents = bp_unpack_value (&bp, 1);
c13bc3d9 4416 ii->member_ptr = bp_unpack_value (&bp, 1);
8b7773a4 4417 ii->by_ref = bp_unpack_value (&bp, 1);
68377e53
JH
4418 ii->maybe_in_construction = bp_unpack_value (&bp, 1);
4419 ii->maybe_derived_type = bp_unpack_value (&bp, 1);
b258210c
MJ
4420 if (ii->polymorphic)
4421 {
412288f1 4422 ii->otr_token = (HOST_WIDE_INT) streamer_read_hwi (ib);
b9393656 4423 ii->otr_type = stream_read_tree (ib, data_in);
68377e53 4424 ii->outer_type = stream_read_tree (ib, data_in);
b258210c 4425 }
661e7330
MJ
4426}
4427
fb3f88cc
JH
4428/* Stream out NODE info to OB. */
4429
4430static void
4431ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
4432{
4433 int node_ref;
7380e6ef 4434 lto_symtab_encoder_t encoder;
fb3f88cc
JH
4435 struct ipa_node_params *info = IPA_NODE_REF (node);
4436 int j;
4437 struct cgraph_edge *e;
2465dcc2 4438 struct bitpack_d bp;
fb3f88cc 4439
7380e6ef 4440 encoder = ob->decl_state->symtab_node_encoder;
67348ccc 4441 node_ref = lto_symtab_encoder_encode (encoder, node);
412288f1 4442 streamer_write_uhwi (ob, node_ref);
fb3f88cc 4443
0e8853ee
JH
4444 streamer_write_uhwi (ob, ipa_get_param_count (info));
4445 for (j = 0; j < ipa_get_param_count (info); j++)
4446 streamer_write_uhwi (ob, ipa_get_param_move_cost (info, j));
2465dcc2 4447 bp = bitpack_create (ob->main_stream);
062c604f 4448 gcc_assert (info->uses_analysis_done
661e7330 4449 || ipa_get_param_count (info) == 0);
fb3f88cc
JH
4450 gcc_assert (!info->node_enqueued);
4451 gcc_assert (!info->ipcp_orig_node);
4452 for (j = 0; j < ipa_get_param_count (info); j++)
310bc633 4453 bp_pack_value (&bp, ipa_is_param_used (info, j), 1);
412288f1 4454 streamer_write_bitpack (&bp);
4502fe8d
MJ
4455 for (j = 0; j < ipa_get_param_count (info); j++)
4456 streamer_write_hwi (ob, ipa_get_controlled_uses (info, j));
fb3f88cc
JH
4457 for (e = node->callees; e; e = e->next_callee)
4458 {
4459 struct ipa_edge_args *args = IPA_EDGE_REF (e);
4460
412288f1 4461 streamer_write_uhwi (ob, ipa_get_cs_argument_count (args));
fb3f88cc
JH
4462 for (j = 0; j < ipa_get_cs_argument_count (args); j++)
4463 ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
4464 }
e33c6cd6 4465 for (e = node->indirect_calls; e; e = e->next_callee)
c8246dbe
JH
4466 {
4467 struct ipa_edge_args *args = IPA_EDGE_REF (e);
4468
412288f1 4469 streamer_write_uhwi (ob, ipa_get_cs_argument_count (args));
c8246dbe
JH
4470 for (j = 0; j < ipa_get_cs_argument_count (args); j++)
4471 ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
4472 ipa_write_indirect_edge_info (ob, e);
4473 }
fb3f88cc
JH
4474}
4475
61502ca8 4476/* Stream in NODE info from IB. */
fb3f88cc
JH
4477
4478static void
4479ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
4480 struct data_in *data_in)
4481{
4482 struct ipa_node_params *info = IPA_NODE_REF (node);
4483 int k;
4484 struct cgraph_edge *e;
2465dcc2 4485 struct bitpack_d bp;
fb3f88cc 4486
0e8853ee 4487 ipa_alloc_node_params (node, streamer_read_uhwi (ib));
fb3f88cc 4488
0e8853ee
JH
4489 for (k = 0; k < ipa_get_param_count (info); k++)
4490 info->descriptors[k].move_cost = streamer_read_uhwi (ib);
4491
412288f1 4492 bp = streamer_read_bitpack (ib);
fb3f88cc 4493 if (ipa_get_param_count (info) != 0)
062c604f 4494 info->uses_analysis_done = true;
fb3f88cc
JH
4495 info->node_enqueued = false;
4496 for (k = 0; k < ipa_get_param_count (info); k++)
310bc633 4497 ipa_set_param_used (info, k, bp_unpack_value (&bp, 1));
1b14621a
MJ
4498 for (k = 0; k < ipa_get_param_count (info); k++)
4499 ipa_set_controlled_uses (info, k, streamer_read_hwi (ib));
fb3f88cc
JH
4500 for (e = node->callees; e; e = e->next_callee)
4501 {
4502 struct ipa_edge_args *args = IPA_EDGE_REF (e);
412288f1 4503 int count = streamer_read_uhwi (ib);
fb3f88cc 4504
fb3f88cc
JH
4505 if (!count)
4506 continue;
9771b263 4507 vec_safe_grow_cleared (args->jump_functions, count);
fb3f88cc 4508
fb3f88cc 4509 for (k = 0; k < ipa_get_cs_argument_count (args); k++)
4502fe8d
MJ
4510 ipa_read_jump_function (ib, ipa_get_ith_jump_func (args, k), e,
4511 data_in);
fb3f88cc 4512 }
e33c6cd6 4513 for (e = node->indirect_calls; e; e = e->next_callee)
c8246dbe
JH
4514 {
4515 struct ipa_edge_args *args = IPA_EDGE_REF (e);
412288f1 4516 int count = streamer_read_uhwi (ib);
c8246dbe 4517
c8246dbe
JH
4518 if (count)
4519 {
9771b263 4520 vec_safe_grow_cleared (args->jump_functions, count);
c8246dbe 4521 for (k = 0; k < ipa_get_cs_argument_count (args); k++)
4502fe8d 4522 ipa_read_jump_function (ib, ipa_get_ith_jump_func (args, k), e,
606d9a09 4523 data_in);
c8246dbe
JH
4524 }
4525 ipa_read_indirect_edge_info (ib, data_in, e);
4526 }
fb3f88cc
JH
4527}
4528
4529/* Write jump functions for nodes in SET. */
4530
4531void
f27c1867 4532ipa_prop_write_jump_functions (void)
fb3f88cc
JH
4533{
4534 struct cgraph_node *node;
93536c97 4535 struct output_block *ob;
fb3f88cc 4536 unsigned int count = 0;
f27c1867
JH
4537 lto_symtab_encoder_iterator lsei;
4538 lto_symtab_encoder_t encoder;
4539
fb3f88cc 4540
9771b263 4541 if (!ipa_node_params_vector.exists ())
93536c97 4542 return;
fb3f88cc 4543
93536c97 4544 ob = create_output_block (LTO_section_jump_functions);
f27c1867 4545 encoder = ob->decl_state->symtab_node_encoder;
93536c97 4546 ob->cgraph_node = NULL;
f27c1867
JH
4547 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
4548 lsei_next_function_in_partition (&lsei))
fb3f88cc 4549 {
f27c1867 4550 node = lsei_cgraph_node (lsei);
c47d0034
JH
4551 if (cgraph_function_with_gimple_body_p (node)
4552 && IPA_NODE_REF (node) != NULL)
fb3f88cc
JH
4553 count++;
4554 }
4555
412288f1 4556 streamer_write_uhwi (ob, count);
fb3f88cc
JH
4557
4558 /* Process all of the functions. */
f27c1867
JH
4559 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
4560 lsei_next_function_in_partition (&lsei))
fb3f88cc 4561 {
f27c1867 4562 node = lsei_cgraph_node (lsei);
c47d0034
JH
4563 if (cgraph_function_with_gimple_body_p (node)
4564 && IPA_NODE_REF (node) != NULL)
fb3f88cc
JH
4565 ipa_write_node_info (ob, node);
4566 }
412288f1 4567 streamer_write_char_stream (ob->main_stream, 0);
fb3f88cc
JH
4568 produce_asm (ob, NULL);
4569 destroy_output_block (ob);
4570}
4571
4572/* Read section in file FILE_DATA of length LEN with data DATA. */
4573
4574static void
4575ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
4576 size_t len)
4577{
4578 const struct lto_function_header *header =
4579 (const struct lto_function_header *) data;
4ad9a9de
EB
4580 const int cfg_offset = sizeof (struct lto_function_header);
4581 const int main_offset = cfg_offset + header->cfg_size;
4582 const int string_offset = main_offset + header->main_size;
fb3f88cc
JH
4583 struct data_in *data_in;
4584 struct lto_input_block ib_main;
4585 unsigned int i;
4586 unsigned int count;
4587
4588 LTO_INIT_INPUT_BLOCK (ib_main, (const char *) data + main_offset, 0,
4589 header->main_size);
4590
4591 data_in =
4592 lto_data_in_create (file_data, (const char *) data + string_offset,
6e1aa848 4593 header->string_size, vNULL);
412288f1 4594 count = streamer_read_uhwi (&ib_main);
fb3f88cc
JH
4595
4596 for (i = 0; i < count; i++)
4597 {
4598 unsigned int index;
4599 struct cgraph_node *node;
7380e6ef 4600 lto_symtab_encoder_t encoder;
fb3f88cc 4601
412288f1 4602 index = streamer_read_uhwi (&ib_main);
7380e6ef
JH
4603 encoder = file_data->symtab_node_encoder;
4604 node = cgraph (lto_symtab_encoder_deref (encoder, index));
67348ccc 4605 gcc_assert (node->definition);
fb3f88cc
JH
4606 ipa_read_node_info (&ib_main, node, data_in);
4607 }
4608 lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
4609 len);
4610 lto_data_in_delete (data_in);
4611}
4612
4613/* Read ipcp jump functions. */
4614
4615void
4616ipa_prop_read_jump_functions (void)
4617{
4618 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
4619 struct lto_file_decl_data *file_data;
4620 unsigned int j = 0;
4621
4622 ipa_check_create_node_params ();
4623 ipa_check_create_edge_args ();
4624 ipa_register_cgraph_hooks ();
4625
4626 while ((file_data = file_data_vec[j++]))
4627 {
4628 size_t len;
4629 const char *data = lto_get_section_data (file_data, LTO_section_jump_functions, NULL, &len);
4630
4631 if (data)
4632 ipa_prop_read_section (file_data, data, len);
4633 }
4634}
4635
b8698a0f 4636/* After merging units, we can get mismatch in argument counts.
61502ca8 4637 Also decl merging might've rendered parameter lists obsolete.
fb3f88cc
JH
4638 Also compute called_with_variable_arg info. */
4639
4640void
4641ipa_update_after_lto_read (void)
4642{
05d3aa37
MJ
4643 ipa_check_create_node_params ();
4644 ipa_check_create_edge_args ();
fb3f88cc 4645}
2c9561b5
MJ
4646
4647void
4648write_agg_replacement_chain (struct output_block *ob, struct cgraph_node *node)
4649{
4650 int node_ref;
4651 unsigned int count = 0;
4652 lto_symtab_encoder_t encoder;
4653 struct ipa_agg_replacement_value *aggvals, *av;
4654
4655 aggvals = ipa_get_agg_replacements_for_node (node);
4656 encoder = ob->decl_state->symtab_node_encoder;
67348ccc 4657 node_ref = lto_symtab_encoder_encode (encoder, node);
2c9561b5
MJ
4658 streamer_write_uhwi (ob, node_ref);
4659
4660 for (av = aggvals; av; av = av->next)
4661 count++;
4662 streamer_write_uhwi (ob, count);
4663
4664 for (av = aggvals; av; av = av->next)
4665 {
7b920a9a
MJ
4666 struct bitpack_d bp;
4667
2c9561b5
MJ
4668 streamer_write_uhwi (ob, av->offset);
4669 streamer_write_uhwi (ob, av->index);
4670 stream_write_tree (ob, av->value, true);
7b920a9a
MJ
4671
4672 bp = bitpack_create (ob->main_stream);
4673 bp_pack_value (&bp, av->by_ref, 1);
4674 streamer_write_bitpack (&bp);
2c9561b5
MJ
4675 }
4676}
4677
4678/* Stream in the aggregate value replacement chain for NODE from IB. */
4679
4680static void
4681read_agg_replacement_chain (struct lto_input_block *ib,
4682 struct cgraph_node *node,
4683 struct data_in *data_in)
4684{
4685 struct ipa_agg_replacement_value *aggvals = NULL;
4686 unsigned int count, i;
4687
4688 count = streamer_read_uhwi (ib);
4689 for (i = 0; i <count; i++)
4690 {
4691 struct ipa_agg_replacement_value *av;
7b920a9a 4692 struct bitpack_d bp;
2c9561b5 4693
766090c2 4694 av = ggc_alloc<ipa_agg_replacement_value> ();
2c9561b5
MJ
4695 av->offset = streamer_read_uhwi (ib);
4696 av->index = streamer_read_uhwi (ib);
4697 av->value = stream_read_tree (ib, data_in);
7b920a9a
MJ
4698 bp = streamer_read_bitpack (ib);
4699 av->by_ref = bp_unpack_value (&bp, 1);
2c9561b5
MJ
4700 av->next = aggvals;
4701 aggvals = av;
4702 }
4703 ipa_set_node_agg_value_chain (node, aggvals);
4704}
4705
4706/* Write all aggregate replacement for nodes in set. */
4707
4708void
4709ipa_prop_write_all_agg_replacement (void)
4710{
4711 struct cgraph_node *node;
4712 struct output_block *ob;
4713 unsigned int count = 0;
4714 lto_symtab_encoder_iterator lsei;
4715 lto_symtab_encoder_t encoder;
4716
4717 if (!ipa_node_agg_replacements)
4718 return;
4719
4720 ob = create_output_block (LTO_section_ipcp_transform);
4721 encoder = ob->decl_state->symtab_node_encoder;
4722 ob->cgraph_node = NULL;
4723 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
4724 lsei_next_function_in_partition (&lsei))
4725 {
4726 node = lsei_cgraph_node (lsei);
4727 if (cgraph_function_with_gimple_body_p (node)
4728 && ipa_get_agg_replacements_for_node (node) != NULL)
4729 count++;
4730 }
4731
4732 streamer_write_uhwi (ob, count);
4733
4734 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
4735 lsei_next_function_in_partition (&lsei))
4736 {
4737 node = lsei_cgraph_node (lsei);
4738 if (cgraph_function_with_gimple_body_p (node)
4739 && ipa_get_agg_replacements_for_node (node) != NULL)
4740 write_agg_replacement_chain (ob, node);
4741 }
4742 streamer_write_char_stream (ob->main_stream, 0);
4743 produce_asm (ob, NULL);
4744 destroy_output_block (ob);
4745}
4746
4747/* Read replacements section in file FILE_DATA of length LEN with data
4748 DATA. */
4749
4750static void
4751read_replacements_section (struct lto_file_decl_data *file_data,
4752 const char *data,
4753 size_t len)
4754{
4755 const struct lto_function_header *header =
4756 (const struct lto_function_header *) data;
4757 const int cfg_offset = sizeof (struct lto_function_header);
4758 const int main_offset = cfg_offset + header->cfg_size;
4759 const int string_offset = main_offset + header->main_size;
4760 struct data_in *data_in;
4761 struct lto_input_block ib_main;
4762 unsigned int i;
4763 unsigned int count;
4764
4765 LTO_INIT_INPUT_BLOCK (ib_main, (const char *) data + main_offset, 0,
4766 header->main_size);
4767
4768 data_in = lto_data_in_create (file_data, (const char *) data + string_offset,
6e1aa848 4769 header->string_size, vNULL);
2c9561b5
MJ
4770 count = streamer_read_uhwi (&ib_main);
4771
4772 for (i = 0; i < count; i++)
4773 {
4774 unsigned int index;
4775 struct cgraph_node *node;
4776 lto_symtab_encoder_t encoder;
4777
4778 index = streamer_read_uhwi (&ib_main);
4779 encoder = file_data->symtab_node_encoder;
4780 node = cgraph (lto_symtab_encoder_deref (encoder, index));
67348ccc 4781 gcc_assert (node->definition);
2c9561b5
MJ
4782 read_agg_replacement_chain (&ib_main, node, data_in);
4783 }
4784 lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
4785 len);
4786 lto_data_in_delete (data_in);
4787}
4788
4789/* Read IPA-CP aggregate replacements. */
4790
4791void
4792ipa_prop_read_all_agg_replacement (void)
4793{
4794 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
4795 struct lto_file_decl_data *file_data;
4796 unsigned int j = 0;
4797
4798 while ((file_data = file_data_vec[j++]))
4799 {
4800 size_t len;
4801 const char *data = lto_get_section_data (file_data,
4802 LTO_section_ipcp_transform,
4803 NULL, &len);
4804 if (data)
4805 read_replacements_section (file_data, data, len);
4806 }
4807}
4808
4809/* Adjust the aggregate replacements in AGGVAL to reflect parameters skipped in
4810 NODE. */
4811
4812static void
4813adjust_agg_replacement_values (struct cgraph_node *node,
4814 struct ipa_agg_replacement_value *aggval)
4815{
4816 struct ipa_agg_replacement_value *v;
4817 int i, c = 0, d = 0, *adj;
4818
4819 if (!node->clone.combined_args_to_skip)
4820 return;
4821
4822 for (v = aggval; v; v = v->next)
4823 {
4824 gcc_assert (v->index >= 0);
4825 if (c < v->index)
4826 c = v->index;
4827 }
4828 c++;
4829
4830 adj = XALLOCAVEC (int, c);
4831 for (i = 0; i < c; i++)
4832 if (bitmap_bit_p (node->clone.combined_args_to_skip, i))
4833 {
4834 adj[i] = -1;
4835 d++;
4836 }
4837 else
4838 adj[i] = i - d;
4839
4840 for (v = aggval; v; v = v->next)
4841 v->index = adj[v->index];
4842}
4843
4844
4845/* Function body transformation phase. */
4846
4847unsigned int
4848ipcp_transform_function (struct cgraph_node *node)
4849{
84562394 4850 vec<ipa_param_descriptor> descriptors = vNULL;
2c9561b5
MJ
4851 struct param_analysis_info *parms_ainfo;
4852 struct ipa_agg_replacement_value *aggval;
4853 gimple_stmt_iterator gsi;
4854 basic_block bb;
4855 int param_count;
4856 bool cfg_changed = false, something_changed = false;
4857
4858 gcc_checking_assert (cfun);
4859 gcc_checking_assert (current_function_decl);
4860
4861 if (dump_file)
4862 fprintf (dump_file, "Modification phase of node %s/%i\n",
fec39fa6 4863 node->name (), node->order);
2c9561b5
MJ
4864
4865 aggval = ipa_get_agg_replacements_for_node (node);
4866 if (!aggval)
4867 return 0;
67348ccc 4868 param_count = count_formal_params (node->decl);
2c9561b5
MJ
4869 if (param_count == 0)
4870 return 0;
4871 adjust_agg_replacement_values (node, aggval);
4872 if (dump_file)
4873 ipa_dump_agg_replacement_values (dump_file, aggval);
4874 parms_ainfo = XALLOCAVEC (struct param_analysis_info, param_count);
4875 memset (parms_ainfo, 0, sizeof (struct param_analysis_info) * param_count);
9771b263 4876 descriptors.safe_grow_cleared (param_count);
2c9561b5
MJ
4877 ipa_populate_param_decls (node, descriptors);
4878
11cd3bed 4879 FOR_EACH_BB_FN (bb, cfun)
2c9561b5
MJ
4880 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
4881 {
4882 struct ipa_agg_replacement_value *v;
4883 gimple stmt = gsi_stmt (gsi);
4884 tree rhs, val, t;
3ff2ca23 4885 HOST_WIDE_INT offset, size;
2c9561b5
MJ
4886 int index;
4887 bool by_ref, vce;
4888
4889 if (!gimple_assign_load_p (stmt))
4890 continue;
4891 rhs = gimple_assign_rhs1 (stmt);
4892 if (!is_gimple_reg_type (TREE_TYPE (rhs)))
4893 continue;
4894
4895 vce = false;
4896 t = rhs;
4897 while (handled_component_p (t))
4898 {
4899 /* V_C_E can do things like convert an array of integers to one
4900 bigger integer and similar things we do not handle below. */
4901 if (TREE_CODE (rhs) == VIEW_CONVERT_EXPR)
4902 {
4903 vce = true;
4904 break;
4905 }
4906 t = TREE_OPERAND (t, 0);
4907 }
4908 if (vce)
4909 continue;
4910
4911 if (!ipa_load_from_parm_agg_1 (descriptors, parms_ainfo, stmt,
3ff2ca23 4912 rhs, &index, &offset, &size, &by_ref))
2c9561b5
MJ
4913 continue;
4914 for (v = aggval; v; v = v->next)
4915 if (v->index == index
4916 && v->offset == offset)
4917 break;
3ff2ca23
JJ
4918 if (!v
4919 || v->by_ref != by_ref
9439e9a1 4920 || tree_to_shwi (TYPE_SIZE (TREE_TYPE (v->value))) != size)
2c9561b5
MJ
4921 continue;
4922
4923 gcc_checking_assert (is_gimple_ip_invariant (v->value));
4924 if (!useless_type_conversion_p (TREE_TYPE (rhs), TREE_TYPE (v->value)))
4925 {
4926 if (fold_convertible_p (TREE_TYPE (rhs), v->value))
4927 val = fold_build1 (NOP_EXPR, TREE_TYPE (rhs), v->value);
4928 else if (TYPE_SIZE (TREE_TYPE (rhs))
4929 == TYPE_SIZE (TREE_TYPE (v->value)))
4930 val = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (rhs), v->value);
4931 else
4932 {
4933 if (dump_file)
4934 {
4935 fprintf (dump_file, " const ");
4936 print_generic_expr (dump_file, v->value, 0);
4937 fprintf (dump_file, " can't be converted to type of ");
4938 print_generic_expr (dump_file, rhs, 0);
4939 fprintf (dump_file, "\n");
4940 }
4941 continue;
4942 }
4943 }
4944 else
4945 val = v->value;
4946
4947 if (dump_file && (dump_flags & TDF_DETAILS))
4948 {
4949 fprintf (dump_file, "Modifying stmt:\n ");
4950 print_gimple_stmt (dump_file, stmt, 0, 0);
4951 }
4952 gimple_assign_set_rhs_from_tree (&gsi, val);
4953 update_stmt (stmt);
4954
4955 if (dump_file && (dump_flags & TDF_DETAILS))
4956 {
4957 fprintf (dump_file, "into:\n ");
4958 print_gimple_stmt (dump_file, stmt, 0, 0);
4959 fprintf (dump_file, "\n");
4960 }
4961
4962 something_changed = true;
4963 if (maybe_clean_eh_stmt (stmt)
4964 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
4965 cfg_changed = true;
4966 }
4967
9771b263 4968 (*ipa_node_agg_replacements)[node->uid] = NULL;
2c9561b5 4969 free_parms_ainfo (parms_ainfo, param_count);
9771b263 4970 descriptors.release ();
2c9561b5
MJ
4971
4972 if (!something_changed)
4973 return 0;
4974 else if (cfg_changed)
4975 return TODO_update_ssa_only_virtuals | TODO_cleanup_cfg;
4976 else
4977 return TODO_update_ssa_only_virtuals;
4978}