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