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