]> gcc.gnu.org Git - gcc.git/blame - gcc/ipa-prop.c
predicates.md (expandable_comparison_operator): New predicate, extracted from...
[gcc.git] / gcc / ipa-prop.c
CommitLineData
518dc859 1/* Interprocedural analyses.
ddb555ed 2 Copyright (C) 2005, 2007, 2008, 2009, 2010, 2011
c75c517d 3 Free Software Foundation, Inc.
518dc859
RL
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9dcd6f09 9Software Foundation; either version 3, or (at your option) any later
518dc859
RL
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
9dcd6f09
NC
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
518dc859
RL
20
21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
24#include "tree.h"
25#include "langhooks.h"
26#include "ggc.h"
27#include "target.h"
28#include "cgraph.h"
29#include "ipa-prop.h"
30#include "tree-flow.h"
31#include "tree-pass.h"
771578a0 32#include "tree-inline.h"
b258210c 33#include "gimple.h"
518dc859
RL
34#include "flags.h"
35#include "timevar.h"
771578a0 36#include "flags.h"
3e293154 37#include "diagnostic.h"
cf835838
JM
38#include "tree-pretty-print.h"
39#include "gimple-pretty-print.h"
fb3f88cc 40#include "lto-streamer.h"
f0efc7aa
DN
41#include "data-streamer.h"
42#include "tree-streamer.h"
771578a0 43
062c604f
MJ
44
45/* Intermediate information about a parameter that is only useful during the
46 run of ipa_analyze_node and is not kept afterwards. */
47
48struct param_analysis_info
49{
50 bool modified;
51 bitmap visited_statements;
52};
53
771578a0
MJ
54/* Vector where the parameter infos are actually stored. */
55VEC (ipa_node_params_t, heap) *ipa_node_params_vector;
56/* Vector where the parameter infos are actually stored. */
fb3f88cc 57VEC (ipa_edge_args_t, gc) *ipa_edge_args_vector;
771578a0 58
e33c6cd6
MJ
59/* Bitmap with all UIDs of call graph edges that have been already processed
60 by indirect inlining. */
61static bitmap iinlining_processed_edges;
62
771578a0 63/* Holders of ipa cgraph hooks: */
e2c9111c
JH
64static struct cgraph_edge_hook_list *edge_removal_hook_holder;
65static struct cgraph_node_hook_list *node_removal_hook_holder;
66static struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
67static struct cgraph_2node_hook_list *node_duplication_hook_holder;
40982661 68static struct cgraph_node_hook_list *function_insertion_hook_holder;
518dc859 69
be95e2b9
MJ
70/* Return index of the formal whose tree is PTREE in function which corresponds
71 to INFO. */
72
632b4f8e 73int
dcd416e3 74ipa_get_param_decl_index (struct ipa_node_params *info, tree ptree)
518dc859
RL
75{
76 int i, count;
77
dcd416e3 78 count = ipa_get_param_count (info);
518dc859 79 for (i = 0; i < count; i++)
310bc633 80 if (ipa_get_param (info, i) == ptree)
518dc859
RL
81 return i;
82
83 return -1;
84}
85
f8e2a1ed
MJ
86/* Populate the param_decl field in parameter descriptors of INFO that
87 corresponds to NODE. */
be95e2b9 88
f8e2a1ed
MJ
89static void
90ipa_populate_param_decls (struct cgraph_node *node,
91 struct ipa_node_params *info)
518dc859
RL
92{
93 tree fndecl;
94 tree fnargs;
95 tree parm;
96 int param_num;
3e293154 97
f8e2a1ed 98 fndecl = node->decl;
518dc859
RL
99 fnargs = DECL_ARGUMENTS (fndecl);
100 param_num = 0;
910ad8de 101 for (parm = fnargs; parm; parm = DECL_CHAIN (parm))
518dc859 102 {
310bc633
MJ
103 VEC_index (ipa_param_descriptor_t,
104 info->descriptors, param_num)->decl = parm;
518dc859
RL
105 param_num++;
106 }
107}
108
3f84bf08
MJ
109/* Return how many formal parameters FNDECL has. */
110
111static inline int
310bc633 112count_formal_params (tree fndecl)
3f84bf08
MJ
113{
114 tree parm;
115 int count = 0;
116
910ad8de 117 for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
3f84bf08
MJ
118 count++;
119
120 return count;
121}
122
f8e2a1ed
MJ
123/* Initialize the ipa_node_params structure associated with NODE by counting
124 the function parameters, creating the descriptors and populating their
125 param_decls. */
be95e2b9 126
f8e2a1ed
MJ
127void
128ipa_initialize_node_params (struct cgraph_node *node)
129{
130 struct ipa_node_params *info = IPA_NODE_REF (node);
131
310bc633 132 if (!info->descriptors)
f8e2a1ed 133 {
310bc633
MJ
134 int param_count;
135
136 param_count = count_formal_params (node->decl);
137 if (param_count)
138 {
139 VEC_safe_grow_cleared (ipa_param_descriptor_t, heap,
140 info->descriptors, param_count);
141 ipa_populate_param_decls (node, info);
142 }
f8e2a1ed 143 }
518dc859
RL
144}
145
749aa96d
MJ
146/* Print the jump functions associated with call graph edge CS to file F. */
147
148static void
149ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
150{
151 int i, count;
152
153 count = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
154 for (i = 0; i < count; i++)
155 {
156 struct ipa_jump_func *jump_func;
157 enum jump_func_type type;
158
159 jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
160 type = jump_func->type;
161
162 fprintf (f, " param %d: ", i);
163 if (type == IPA_JF_UNKNOWN)
164 fprintf (f, "UNKNOWN\n");
165 else if (type == IPA_JF_KNOWN_TYPE)
166 {
167 tree binfo_type = TREE_TYPE (jump_func->value.base_binfo);
168 fprintf (f, "KNOWN TYPE, type in binfo is: ");
169 print_generic_expr (f, binfo_type, 0);
170 fprintf (f, " (%u)\n", TYPE_UID (binfo_type));
171 }
172 else if (type == IPA_JF_CONST)
173 {
174 tree val = jump_func->value.constant;
175 fprintf (f, "CONST: ");
176 print_generic_expr (f, val, 0);
177 if (TREE_CODE (val) == ADDR_EXPR
178 && TREE_CODE (TREE_OPERAND (val, 0)) == CONST_DECL)
179 {
180 fprintf (f, " -> ");
181 print_generic_expr (f, DECL_INITIAL (TREE_OPERAND (val, 0)),
182 0);
183 }
184 fprintf (f, "\n");
185 }
186 else if (type == IPA_JF_CONST_MEMBER_PTR)
187 {
188 fprintf (f, "CONST MEMBER PTR: ");
189 print_generic_expr (f, jump_func->value.member_cst.pfn, 0);
190 fprintf (f, ", ");
191 print_generic_expr (f, jump_func->value.member_cst.delta, 0);
192 fprintf (f, "\n");
193 }
194 else if (type == IPA_JF_PASS_THROUGH)
195 {
196 fprintf (f, "PASS THROUGH: ");
197 fprintf (f, "%d, op %s ",
198 jump_func->value.pass_through.formal_id,
199 tree_code_name[(int)
200 jump_func->value.pass_through.operation]);
201 if (jump_func->value.pass_through.operation != NOP_EXPR)
202 print_generic_expr (dump_file,
203 jump_func->value.pass_through.operand, 0);
204 fprintf (dump_file, "\n");
205 }
206 else if (type == IPA_JF_ANCESTOR)
207 {
208 fprintf (f, "ANCESTOR: ");
209 fprintf (f, "%d, offset "HOST_WIDE_INT_PRINT_DEC", ",
210 jump_func->value.ancestor.formal_id,
211 jump_func->value.ancestor.offset);
212 print_generic_expr (f, jump_func->value.ancestor.type, 0);
213 fprintf (dump_file, "\n");
214 }
215 }
216}
217
218
be95e2b9
MJ
219/* Print the jump functions of all arguments on all call graph edges going from
220 NODE to file F. */
221
518dc859 222void
3e293154 223ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
518dc859 224{
3e293154 225 struct cgraph_edge *cs;
749aa96d 226 int i;
518dc859 227
ca30a539 228 fprintf (f, " Jump functions of caller %s:\n", cgraph_node_name (node));
3e293154
MJ
229 for (cs = node->callees; cs; cs = cs->next_callee)
230 {
231 if (!ipa_edge_args_info_available_for_edge_p (cs))
232 continue;
233
749aa96d
MJ
234 fprintf (f, " callsite %s/%i -> %s/%i : \n",
235 cgraph_node_name (node), node->uid,
236 cgraph_node_name (cs->callee), cs->callee->uid);
237 ipa_print_node_jump_functions_for_edge (f, cs);
238 }
518dc859 239
749aa96d
MJ
240 for (cs = node->indirect_calls, i = 0; cs; cs = cs->next_callee, i++)
241 {
242 if (!ipa_edge_args_info_available_for_edge_p (cs))
243 continue;
3e293154 244
749aa96d
MJ
245 if (cs->call_stmt)
246 {
247 fprintf (f, " indirect callsite %d for stmt ", i);
248 print_gimple_stmt (f, cs->call_stmt, 0, TDF_SLIM);
3e293154 249 }
749aa96d
MJ
250 else
251 fprintf (f, " indirect callsite %d :\n", i);
252 ipa_print_node_jump_functions_for_edge (f, cs);
253
3e293154
MJ
254 }
255}
256
257/* Print ipa_jump_func data structures of all nodes in the call graph to F. */
be95e2b9 258
3e293154
MJ
259void
260ipa_print_all_jump_functions (FILE *f)
261{
262 struct cgraph_node *node;
263
ca30a539 264 fprintf (f, "\nJump functions:\n");
3e293154
MJ
265 for (node = cgraph_nodes; node; node = node->next)
266 {
267 ipa_print_node_jump_functions (f, node);
268 }
269}
270
f65cf2b7
MJ
271/* Structure to be passed in between detect_type_change and
272 check_stmt_for_type_change. */
273
274struct type_change_info
275{
276 /* Set to true if dynamic type change has been detected. */
277 bool type_maybe_changed;
278};
279
280/* Return true if STMT can modify a virtual method table pointer.
281
282 This function makes special assumptions about both constructors and
283 destructors which are all the functions that are allowed to alter the VMT
284 pointers. It assumes that destructors begin with assignment into all VMT
285 pointers and that constructors essentially look in the following way:
286
287 1) The very first thing they do is that they call constructors of ancestor
288 sub-objects that have them.
289
290 2) Then VMT pointers of this and all its ancestors is set to new values
291 corresponding to the type corresponding to the constructor.
292
293 3) Only afterwards, other stuff such as constructor of member sub-objects
294 and the code written by the user is run. Only this may include calling
295 virtual functions, directly or indirectly.
296
297 There is no way to call a constructor of an ancestor sub-object in any
298 other way.
299
300 This means that we do not have to care whether constructors get the correct
301 type information because they will always change it (in fact, if we define
302 the type to be given by the VMT pointer, it is undefined).
303
304 The most important fact to derive from the above is that if, for some
305 statement in the section 3, we try to detect whether the dynamic type has
306 changed, we can safely ignore all calls as we examine the function body
307 backwards until we reach statements in section 2 because these calls cannot
308 be ancestor constructors or destructors (if the input is not bogus) and so
309 do not change the dynamic type (this holds true only for automatically
310 allocated objects but at the moment we devirtualize only these). We then
311 must detect that statements in section 2 change the dynamic type and can try
312 to derive the new type. That is enough and we can stop, we will never see
313 the calls into constructors of sub-objects in this code. Therefore we can
314 safely ignore all call statements that we traverse.
315 */
316
317static bool
318stmt_may_be_vtbl_ptr_store (gimple stmt)
319{
320 if (is_gimple_call (stmt))
321 return false;
322 else if (is_gimple_assign (stmt))
323 {
324 tree lhs = gimple_assign_lhs (stmt);
325
0004f992
MJ
326 if (!AGGREGATE_TYPE_P (TREE_TYPE (lhs)))
327 {
328 if (flag_strict_aliasing
329 && !POINTER_TYPE_P (TREE_TYPE (lhs)))
330 return false;
331
332 if (TREE_CODE (lhs) == COMPONENT_REF
333 && !DECL_VIRTUAL_P (TREE_OPERAND (lhs, 1)))
f65cf2b7 334 return false;
0004f992
MJ
335 /* In the future we might want to use get_base_ref_and_offset to find
336 if there is a field corresponding to the offset and if so, proceed
337 almost like if it was a component ref. */
338 }
f65cf2b7
MJ
339 }
340 return true;
341}
342
61502ca8 343/* Callback of walk_aliased_vdefs and a helper function for
f65cf2b7
MJ
344 detect_type_change to check whether a particular statement may modify
345 the virtual table pointer, and if possible also determine the new type of
346 the (sub-)object. It stores its result into DATA, which points to a
347 type_change_info structure. */
348
349static bool
350check_stmt_for_type_change (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
351{
352 gimple stmt = SSA_NAME_DEF_STMT (vdef);
353 struct type_change_info *tci = (struct type_change_info *) data;
354
355 if (stmt_may_be_vtbl_ptr_store (stmt))
356 {
357 tci->type_maybe_changed = true;
358 return true;
359 }
360 else
361 return false;
362}
363
364/* Detect whether the dynamic type of ARG has changed (before callsite CALL) by
365 looking for assignments to its virtual table pointer. If it is, return true
366 and fill in the jump function JFUNC with relevant type information or set it
367 to unknown. ARG is the object itself (not a pointer to it, unless
368 dereferenced). BASE is the base of the memory access as returned by
369 get_ref_base_and_extent, as is the offset. */
370
371static bool
372detect_type_change (tree arg, tree base, gimple call,
373 struct ipa_jump_func *jfunc, HOST_WIDE_INT offset)
374{
375 struct type_change_info tci;
376 ao_ref ao;
377
378 gcc_checking_assert (DECL_P (arg)
379 || TREE_CODE (arg) == MEM_REF
380 || handled_component_p (arg));
381 /* Const calls cannot call virtual methods through VMT and so type changes do
382 not matter. */
05842ff5 383 if (!flag_devirtualize || !gimple_vuse (call))
f65cf2b7
MJ
384 return false;
385
386 tci.type_maybe_changed = false;
387
388 ao.ref = arg;
389 ao.base = base;
390 ao.offset = offset;
391 ao.size = POINTER_SIZE;
392 ao.max_size = ao.size;
393 ao.ref_alias_set = -1;
394 ao.base_alias_set = -1;
395
396 walk_aliased_vdefs (&ao, gimple_vuse (call), check_stmt_for_type_change,
397 &tci, NULL);
398 if (!tci.type_maybe_changed)
399 return false;
400
401 jfunc->type = IPA_JF_UNKNOWN;
402 return true;
403}
404
405/* Like detect_type_change but ARG is supposed to be a non-dereferenced pointer
406 SSA name (its dereference will become the base and the offset is assumed to
407 be zero). */
408
409static bool
410detect_type_change_ssa (tree arg, gimple call, struct ipa_jump_func *jfunc)
411{
412 gcc_checking_assert (TREE_CODE (arg) == SSA_NAME);
05842ff5
MJ
413 if (!flag_devirtualize
414 || !POINTER_TYPE_P (TREE_TYPE (arg))
f65cf2b7
MJ
415 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != RECORD_TYPE)
416 return false;
417
418 arg = build2 (MEM_REF, ptr_type_node, arg,
419 build_int_cst (ptr_type_node, 0));
420
421 return detect_type_change (arg, arg, call, jfunc, 0);
422}
423
424
b258210c
MJ
425/* Given that an actual argument is an SSA_NAME (given in NAME) and is a result
426 of an assignment statement STMT, try to find out whether NAME can be
427 described by a (possibly polynomial) pass-through jump-function or an
428 ancestor jump function and if so, write the appropriate function into
429 JFUNC */
685b0d13
MJ
430
431static void
b258210c
MJ
432compute_complex_assign_jump_func (struct ipa_node_params *info,
433 struct ipa_jump_func *jfunc,
f65cf2b7 434 gimple call, gimple stmt, tree name)
685b0d13
MJ
435{
436 HOST_WIDE_INT offset, size, max_size;
f65cf2b7 437 tree op1, op2, base, ssa;
685b0d13 438 int index;
685b0d13 439
685b0d13
MJ
440 op1 = gimple_assign_rhs1 (stmt);
441 op2 = gimple_assign_rhs2 (stmt);
442
b258210c
MJ
443 if (TREE_CODE (op1) == SSA_NAME
444 && SSA_NAME_IS_DEFAULT_DEF (op1))
685b0d13 445 {
b258210c
MJ
446 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (op1));
447 if (index < 0)
685b0d13
MJ
448 return;
449
b258210c 450 if (op2)
685b0d13 451 {
b258210c
MJ
452 if (!is_gimple_ip_invariant (op2)
453 || (TREE_CODE_CLASS (gimple_expr_code (stmt)) != tcc_comparison
454 && !useless_type_conversion_p (TREE_TYPE (name),
455 TREE_TYPE (op1))))
456 return;
457
685b0d13
MJ
458 jfunc->type = IPA_JF_PASS_THROUGH;
459 jfunc->value.pass_through.formal_id = index;
460 jfunc->value.pass_through.operation = gimple_assign_rhs_code (stmt);
461 jfunc->value.pass_through.operand = op2;
462 }
f65cf2b7
MJ
463 else if (gimple_assign_unary_nop_p (stmt)
464 && !detect_type_change_ssa (op1, call, jfunc))
b258210c
MJ
465 {
466 jfunc->type = IPA_JF_PASS_THROUGH;
467 jfunc->value.pass_through.formal_id = index;
468 jfunc->value.pass_through.operation = NOP_EXPR;
469 }
685b0d13
MJ
470 return;
471 }
472
473 if (TREE_CODE (op1) != ADDR_EXPR)
474 return;
475 op1 = TREE_OPERAND (op1, 0);
f65cf2b7 476 if (TREE_CODE (TREE_TYPE (op1)) != RECORD_TYPE)
b258210c 477 return;
32aa622c
MJ
478 base = get_ref_base_and_extent (op1, &offset, &size, &max_size);
479 if (TREE_CODE (base) != MEM_REF
1a15bfdc
RG
480 /* If this is a varying address, punt. */
481 || max_size == -1
482 || max_size != size)
685b0d13 483 return;
32aa622c 484 offset += mem_ref_offset (base).low * BITS_PER_UNIT;
f65cf2b7
MJ
485 ssa = TREE_OPERAND (base, 0);
486 if (TREE_CODE (ssa) != SSA_NAME
487 || !SSA_NAME_IS_DEFAULT_DEF (ssa)
280fedf0 488 || offset < 0)
685b0d13
MJ
489 return;
490
32aa622c 491 /* Dynamic types are changed only in constructors and destructors and */
f65cf2b7
MJ
492 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (ssa));
493 if (index >= 0
494 && !detect_type_change (op1, base, call, jfunc, offset))
685b0d13
MJ
495 {
496 jfunc->type = IPA_JF_ANCESTOR;
497 jfunc->value.ancestor.formal_id = index;
498 jfunc->value.ancestor.offset = offset;
f65cf2b7 499 jfunc->value.ancestor.type = TREE_TYPE (op1);
685b0d13
MJ
500 }
501}
502
40591473
MJ
503/* Extract the base, offset and MEM_REF expression from a statement ASSIGN if
504 it looks like:
505
506 iftmp.1_3 = &obj_2(D)->D.1762;
507
508 The base of the MEM_REF must be a default definition SSA NAME of a
509 parameter. Return NULL_TREE if it looks otherwise. If case of success, the
510 whole MEM_REF expression is returned and the offset calculated from any
511 handled components and the MEM_REF itself is stored into *OFFSET. The whole
512 RHS stripped off the ADDR_EXPR is stored into *OBJ_P. */
513
514static tree
515get_ancestor_addr_info (gimple assign, tree *obj_p, HOST_WIDE_INT *offset)
516{
517 HOST_WIDE_INT size, max_size;
518 tree expr, parm, obj;
519
520 if (!gimple_assign_single_p (assign))
521 return NULL_TREE;
522 expr = gimple_assign_rhs1 (assign);
523
524 if (TREE_CODE (expr) != ADDR_EXPR)
525 return NULL_TREE;
526 expr = TREE_OPERAND (expr, 0);
527 obj = expr;
528 expr = get_ref_base_and_extent (expr, offset, &size, &max_size);
529
530 if (TREE_CODE (expr) != MEM_REF
531 /* If this is a varying address, punt. */
532 || max_size == -1
533 || max_size != size
534 || *offset < 0)
535 return NULL_TREE;
536 parm = TREE_OPERAND (expr, 0);
537 if (TREE_CODE (parm) != SSA_NAME
538 || !SSA_NAME_IS_DEFAULT_DEF (parm)
539 || TREE_CODE (SSA_NAME_VAR (parm)) != PARM_DECL)
540 return NULL_TREE;
541
542 *offset += mem_ref_offset (expr).low * BITS_PER_UNIT;
543 *obj_p = obj;
544 return expr;
545}
546
685b0d13 547
b258210c
MJ
548/* Given that an actual argument is an SSA_NAME that is a result of a phi
549 statement PHI, try to find out whether NAME is in fact a
550 multiple-inheritance typecast from a descendant into an ancestor of a formal
551 parameter and thus can be described by an ancestor jump function and if so,
552 write the appropriate function into JFUNC.
553
554 Essentially we want to match the following pattern:
555
556 if (obj_2(D) != 0B)
557 goto <bb 3>;
558 else
559 goto <bb 4>;
560
561 <bb 3>:
562 iftmp.1_3 = &obj_2(D)->D.1762;
563
564 <bb 4>:
565 # iftmp.1_1 = PHI <iftmp.1_3(3), 0B(2)>
566 D.1879_6 = middleman_1 (iftmp.1_1, i_5(D));
567 return D.1879_6; */
568
569static void
570compute_complex_ancestor_jump_func (struct ipa_node_params *info,
571 struct ipa_jump_func *jfunc,
f65cf2b7 572 gimple call, gimple phi)
b258210c 573{
40591473 574 HOST_WIDE_INT offset;
b258210c
MJ
575 gimple assign, cond;
576 basic_block phi_bb, assign_bb, cond_bb;
f65cf2b7 577 tree tmp, parm, expr, obj;
b258210c
MJ
578 int index, i;
579
54e348cb 580 if (gimple_phi_num_args (phi) != 2)
b258210c
MJ
581 return;
582
54e348cb
MJ
583 if (integer_zerop (PHI_ARG_DEF (phi, 1)))
584 tmp = PHI_ARG_DEF (phi, 0);
585 else if (integer_zerop (PHI_ARG_DEF (phi, 0)))
586 tmp = PHI_ARG_DEF (phi, 1);
587 else
588 return;
b258210c
MJ
589 if (TREE_CODE (tmp) != SSA_NAME
590 || SSA_NAME_IS_DEFAULT_DEF (tmp)
591 || !POINTER_TYPE_P (TREE_TYPE (tmp))
592 || TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) != RECORD_TYPE)
593 return;
594
595 assign = SSA_NAME_DEF_STMT (tmp);
596 assign_bb = gimple_bb (assign);
40591473 597 if (!single_pred_p (assign_bb))
b258210c 598 return;
40591473
MJ
599 expr = get_ancestor_addr_info (assign, &obj, &offset);
600 if (!expr)
b258210c
MJ
601 return;
602 parm = TREE_OPERAND (expr, 0);
b258210c 603 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (parm));
40591473 604 gcc_assert (index >= 0);
b258210c
MJ
605
606 cond_bb = single_pred (assign_bb);
607 cond = last_stmt (cond_bb);
69610617
SB
608 if (!cond
609 || gimple_code (cond) != GIMPLE_COND
b258210c
MJ
610 || gimple_cond_code (cond) != NE_EXPR
611 || gimple_cond_lhs (cond) != parm
612 || !integer_zerop (gimple_cond_rhs (cond)))
613 return;
614
b258210c
MJ
615 phi_bb = gimple_bb (phi);
616 for (i = 0; i < 2; i++)
617 {
618 basic_block pred = EDGE_PRED (phi_bb, i)->src;
619 if (pred != assign_bb && pred != cond_bb)
620 return;
621 }
622
f65cf2b7
MJ
623 if (!detect_type_change (obj, expr, call, jfunc, offset))
624 {
625 jfunc->type = IPA_JF_ANCESTOR;
626 jfunc->value.ancestor.formal_id = index;
627 jfunc->value.ancestor.offset = offset;
40591473 628 jfunc->value.ancestor.type = TREE_TYPE (obj);
f65cf2b7 629 }
b258210c
MJ
630}
631
61502ca8 632/* Given OP which is passed as an actual argument to a called function,
b258210c
MJ
633 determine if it is possible to construct a KNOWN_TYPE jump function for it
634 and if so, create one and store it to JFUNC. */
635
636static void
f65cf2b7
MJ
637compute_known_type_jump_func (tree op, struct ipa_jump_func *jfunc,
638 gimple call)
b258210c 639{
32aa622c
MJ
640 HOST_WIDE_INT offset, size, max_size;
641 tree base, binfo;
b258210c 642
05842ff5
MJ
643 if (!flag_devirtualize
644 || TREE_CODE (op) != ADDR_EXPR
32aa622c 645 || TREE_CODE (TREE_TYPE (TREE_TYPE (op))) != RECORD_TYPE)
b258210c
MJ
646 return;
647
648 op = TREE_OPERAND (op, 0);
32aa622c
MJ
649 base = get_ref_base_and_extent (op, &offset, &size, &max_size);
650 if (!DECL_P (base)
651 || max_size == -1
652 || max_size != size
653 || TREE_CODE (TREE_TYPE (base)) != RECORD_TYPE
654 || is_global_var (base))
655 return;
656
f65cf2b7
MJ
657 if (detect_type_change (op, base, call, jfunc, offset))
658 return;
659
32aa622c
MJ
660 binfo = TYPE_BINFO (TREE_TYPE (base));
661 if (!binfo)
662 return;
663 binfo = get_binfo_at_offset (binfo, offset, TREE_TYPE (op));
b258210c
MJ
664 if (binfo)
665 {
666 jfunc->type = IPA_JF_KNOWN_TYPE;
667 jfunc->value.base_binfo = binfo;
668 }
669}
670
671
be95e2b9
MJ
672/* Determine the jump functions of scalar arguments. Scalar means SSA names
673 and constants of a number of selected types. INFO is the ipa_node_params
674 structure associated with the caller, FUNCTIONS is a pointer to an array of
675 jump function structures associated with CALL which is the call statement
676 being examined.*/
677
3e293154
MJ
678static void
679compute_scalar_jump_functions (struct ipa_node_params *info,
606d9a09 680 struct ipa_edge_args *args,
726a989a 681 gimple call)
3e293154 682{
3e293154 683 tree arg;
726a989a 684 unsigned num = 0;
3e293154 685
726a989a 686 for (num = 0; num < gimple_call_num_args (call); num++)
518dc859 687 {
606d9a09 688 struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, num);
726a989a
RB
689 arg = gimple_call_arg (call, num);
690
00fc2333 691 if (is_gimple_ip_invariant (arg))
518dc859 692 {
606d9a09
MJ
693 jfunc->type = IPA_JF_CONST;
694 jfunc->value.constant = arg;
3e293154 695 }
685b0d13 696 else if (TREE_CODE (arg) == SSA_NAME)
3e293154 697 {
685b0d13 698 if (SSA_NAME_IS_DEFAULT_DEF (arg))
518dc859 699 {
685b0d13
MJ
700 int index = ipa_get_param_decl_index (info, SSA_NAME_VAR (arg));
701
f65cf2b7 702 if (index >= 0
606d9a09 703 && !detect_type_change_ssa (arg, call, jfunc))
685b0d13 704 {
606d9a09
MJ
705 jfunc->type = IPA_JF_PASS_THROUGH;
706 jfunc->value.pass_through.formal_id = index;
707 jfunc->value.pass_through.operation = NOP_EXPR;
685b0d13 708 }
518dc859 709 }
685b0d13 710 else
b258210c
MJ
711 {
712 gimple stmt = SSA_NAME_DEF_STMT (arg);
713 if (is_gimple_assign (stmt))
606d9a09 714 compute_complex_assign_jump_func (info, jfunc, call, stmt, arg);
b258210c 715 else if (gimple_code (stmt) == GIMPLE_PHI)
606d9a09 716 compute_complex_ancestor_jump_func (info, jfunc, call, stmt);
b258210c 717 }
518dc859 718 }
b258210c 719 else
606d9a09 720 compute_known_type_jump_func (arg, jfunc, call);
3e293154
MJ
721 }
722}
723
be95e2b9
MJ
724/* Inspect the given TYPE and return true iff it has the same structure (the
725 same number of fields of the same types) as a C++ member pointer. If
726 METHOD_PTR and DELTA are non-NULL, store the trees representing the
727 corresponding fields there. */
728
3e293154
MJ
729static bool
730type_like_member_ptr_p (tree type, tree *method_ptr, tree *delta)
731{
732 tree fld;
733
734 if (TREE_CODE (type) != RECORD_TYPE)
735 return false;
736
737 fld = TYPE_FIELDS (type);
738 if (!fld || !POINTER_TYPE_P (TREE_TYPE (fld))
739 || TREE_CODE (TREE_TYPE (TREE_TYPE (fld))) != METHOD_TYPE)
740 return false;
741
742 if (method_ptr)
743 *method_ptr = fld;
744
910ad8de 745 fld = DECL_CHAIN (fld);
3e293154
MJ
746 if (!fld || INTEGRAL_TYPE_P (fld))
747 return false;
748 if (delta)
749 *delta = fld;
750
910ad8de 751 if (DECL_CHAIN (fld))
3e293154
MJ
752 return false;
753
754 return true;
755}
756
062c604f
MJ
757/* Callback of walk_aliased_vdefs. Flags that it has been invoked to the
758 boolean variable pointed to by DATA. */
759
760static bool
761mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
762 void *data)
763{
764 bool *b = (bool *) data;
765 *b = true;
766 return true;
767}
768
769/* Return true if the formal parameter PARM might have been modified in this
770 function before reaching the statement CALL. PARM_INFO is a pointer to a
771 structure containing intermediate information about PARM. */
772
773static bool
774is_parm_modified_before_call (struct param_analysis_info *parm_info,
775 gimple call, tree parm)
776{
777 bool modified = false;
778 ao_ref refd;
779
780 if (parm_info->modified)
781 return true;
782
783 ao_ref_init (&refd, parm);
784 walk_aliased_vdefs (&refd, gimple_vuse (call), mark_modified,
785 &modified, &parm_info->visited_statements);
786 if (modified)
787 {
788 parm_info->modified = true;
789 return true;
790 }
791 return false;
792}
793
be95e2b9
MJ
794/* Go through arguments of the CALL and for every one that looks like a member
795 pointer, check whether it can be safely declared pass-through and if so,
796 mark that to the corresponding item of jump FUNCTIONS. Return true iff
797 there are non-pass-through member pointers within the arguments. INFO
062c604f
MJ
798 describes formal parameters of the caller. PARMS_INFO is a pointer to a
799 vector containing intermediate information about each formal parameter. */
be95e2b9 800
3e293154
MJ
801static bool
802compute_pass_through_member_ptrs (struct ipa_node_params *info,
062c604f 803 struct param_analysis_info *parms_info,
606d9a09 804 struct ipa_edge_args *args,
726a989a 805 gimple call)
3e293154 806{
3e293154 807 bool undecided_members = false;
726a989a 808 unsigned num;
3e293154
MJ
809 tree arg;
810
726a989a 811 for (num = 0; num < gimple_call_num_args (call); num++)
3e293154 812 {
726a989a
RB
813 arg = gimple_call_arg (call, num);
814
3e293154 815 if (type_like_member_ptr_p (TREE_TYPE (arg), NULL, NULL))
518dc859 816 {
3e293154
MJ
817 if (TREE_CODE (arg) == PARM_DECL)
818 {
819 int index = ipa_get_param_decl_index (info, arg);
820
821 gcc_assert (index >=0);
062c604f 822 if (!is_parm_modified_before_call (&parms_info[index], call, arg))
3e293154 823 {
606d9a09
MJ
824 struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args,
825 num);
826 jfunc->type = IPA_JF_PASS_THROUGH;
827 jfunc->value.pass_through.formal_id = index;
828 jfunc->value.pass_through.operation = NOP_EXPR;
3e293154
MJ
829 }
830 else
831 undecided_members = true;
832 }
833 else
834 undecided_members = true;
518dc859 835 }
3e293154
MJ
836 }
837
838 return undecided_members;
839}
840
841/* Simple function filling in a member pointer constant jump function (with PFN
842 and DELTA as the constant value) into JFUNC. */
be95e2b9 843
3e293154
MJ
844static void
845fill_member_ptr_cst_jump_function (struct ipa_jump_func *jfunc,
846 tree pfn, tree delta)
847{
133f9369 848 jfunc->type = IPA_JF_CONST_MEMBER_PTR;
3e293154
MJ
849 jfunc->value.member_cst.pfn = pfn;
850 jfunc->value.member_cst.delta = delta;
851}
852
61502ca8 853/* If RHS is an SSA_NAME and it is defined by a simple copy assign statement,
7ec49257
MJ
854 return the rhs of its defining statement. */
855
856static inline tree
857get_ssa_def_if_simple_copy (tree rhs)
858{
859 while (TREE_CODE (rhs) == SSA_NAME && !SSA_NAME_IS_DEFAULT_DEF (rhs))
860 {
861 gimple def_stmt = SSA_NAME_DEF_STMT (rhs);
862
863 if (gimple_assign_single_p (def_stmt))
864 rhs = gimple_assign_rhs1 (def_stmt);
9961eb45
MJ
865 else
866 break;
7ec49257
MJ
867 }
868 return rhs;
869}
870
726a989a
RB
871/* Traverse statements from CALL backwards, scanning whether the argument ARG
872 which is a member pointer is filled in with constant values. If it is, fill
873 the jump function JFUNC in appropriately. METHOD_FIELD and DELTA_FIELD are
874 fields of the record type of the member pointer. To give an example, we
875 look for a pattern looking like the following:
3e293154
MJ
876
877 D.2515.__pfn ={v} printStuff;
878 D.2515.__delta ={v} 0;
879 i_1 = doprinting (D.2515); */
be95e2b9 880
3e293154 881static void
726a989a 882determine_cst_member_ptr (gimple call, tree arg, tree method_field,
3e293154
MJ
883 tree delta_field, struct ipa_jump_func *jfunc)
884{
726a989a 885 gimple_stmt_iterator gsi;
3e293154
MJ
886 tree method = NULL_TREE;
887 tree delta = NULL_TREE;
888
726a989a 889 gsi = gsi_for_stmt (call);
3e293154 890
726a989a
RB
891 gsi_prev (&gsi);
892 for (; !gsi_end_p (gsi); gsi_prev (&gsi))
3e293154 893 {
726a989a 894 gimple stmt = gsi_stmt (gsi);
3e293154
MJ
895 tree lhs, rhs, fld;
896
8aa29647
MJ
897 if (!stmt_may_clobber_ref_p (stmt, arg))
898 continue;
8b75fc9b 899 if (!gimple_assign_single_p (stmt))
3e293154
MJ
900 return;
901
726a989a
RB
902 lhs = gimple_assign_lhs (stmt);
903 rhs = gimple_assign_rhs1 (stmt);
3e293154
MJ
904
905 if (TREE_CODE (lhs) != COMPONENT_REF
906 || TREE_OPERAND (lhs, 0) != arg)
8aa29647 907 return;
3e293154
MJ
908
909 fld = TREE_OPERAND (lhs, 1);
910 if (!method && fld == method_field)
518dc859 911 {
7ec49257 912 rhs = get_ssa_def_if_simple_copy (rhs);
3e293154
MJ
913 if (TREE_CODE (rhs) == ADDR_EXPR
914 && TREE_CODE (TREE_OPERAND (rhs, 0)) == FUNCTION_DECL
915 && TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs, 0))) == METHOD_TYPE)
518dc859 916 {
3e293154
MJ
917 method = TREE_OPERAND (rhs, 0);
918 if (delta)
919 {
00fc2333 920 fill_member_ptr_cst_jump_function (jfunc, rhs, delta);
3e293154
MJ
921 return;
922 }
518dc859 923 }
3e293154
MJ
924 else
925 return;
926 }
927
928 if (!delta && fld == delta_field)
929 {
7ec49257 930 rhs = get_ssa_def_if_simple_copy (rhs);
3e293154
MJ
931 if (TREE_CODE (rhs) == INTEGER_CST)
932 {
933 delta = rhs;
934 if (method)
935 {
00fc2333 936 fill_member_ptr_cst_jump_function (jfunc, rhs, delta);
3e293154
MJ
937 return;
938 }
939 }
940 else
941 return;
942 }
943 }
944
945 return;
946}
947
726a989a
RB
948/* Go through the arguments of the CALL and for every member pointer within
949 tries determine whether it is a constant. If it is, create a corresponding
950 constant jump function in FUNCTIONS which is an array of jump functions
951 associated with the call. */
be95e2b9 952
3e293154 953static void
606d9a09 954compute_cst_member_ptr_arguments (struct ipa_edge_args *args,
726a989a 955 gimple call)
3e293154 956{
726a989a 957 unsigned num;
3e293154
MJ
958 tree arg, method_field, delta_field;
959
726a989a 960 for (num = 0; num < gimple_call_num_args (call); num++)
3e293154 961 {
606d9a09 962 struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, num);
726a989a
RB
963 arg = gimple_call_arg (call, num);
964
606d9a09 965 if (jfunc->type == IPA_JF_UNKNOWN
3e293154
MJ
966 && type_like_member_ptr_p (TREE_TYPE (arg), &method_field,
967 &delta_field))
606d9a09 968 determine_cst_member_ptr (call, arg, method_field, delta_field, jfunc);
3e293154
MJ
969 }
970}
971
972/* Compute jump function for all arguments of callsite CS and insert the
973 information in the jump_functions array in the ipa_edge_args corresponding
974 to this callsite. */
be95e2b9 975
749aa96d 976static void
062c604f
MJ
977ipa_compute_jump_functions_for_edge (struct param_analysis_info *parms_info,
978 struct cgraph_edge *cs)
3e293154
MJ
979{
980 struct ipa_node_params *info = IPA_NODE_REF (cs->caller);
606d9a09
MJ
981 struct ipa_edge_args *args = IPA_EDGE_REF (cs);
982 gimple call = cs->call_stmt;
983 int arg_num = gimple_call_num_args (call);
3e293154 984
606d9a09 985 if (arg_num == 0 || args->jump_functions)
3e293154 986 return;
606d9a09 987 VEC_safe_grow_cleared (ipa_jump_func_t, gc, args->jump_functions, arg_num);
3e293154
MJ
988
989 /* We will deal with constants and SSA scalars first: */
606d9a09 990 compute_scalar_jump_functions (info, args, call);
3e293154
MJ
991
992 /* Let's check whether there are any potential member pointers and if so,
993 whether we can determine their functions as pass_through. */
606d9a09 994 if (!compute_pass_through_member_ptrs (info, parms_info, args, call))
3e293154
MJ
995 return;
996
be95e2b9 997 /* Finally, let's check whether we actually pass a new constant member
3e293154 998 pointer here... */
606d9a09 999 compute_cst_member_ptr_arguments (args, call);
3e293154
MJ
1000}
1001
749aa96d
MJ
1002/* Compute jump functions for all edges - both direct and indirect - outgoing
1003 from NODE. Also count the actual arguments in the process. */
1004
062c604f
MJ
1005static void
1006ipa_compute_jump_functions (struct cgraph_node *node,
1007 struct param_analysis_info *parms_info)
749aa96d
MJ
1008{
1009 struct cgraph_edge *cs;
1010
1011 for (cs = node->callees; cs; cs = cs->next_callee)
1012 {
d7da5cc8
MJ
1013 struct cgraph_node *callee = cgraph_function_or_thunk_node (cs->callee,
1014 NULL);
749aa96d
MJ
1015 /* We do not need to bother analyzing calls to unknown
1016 functions unless they may become known during lto/whopr. */
d7da5cc8 1017 if (!callee->analyzed && !flag_lto)
749aa96d 1018 continue;
062c604f 1019 ipa_compute_jump_functions_for_edge (parms_info, cs);
749aa96d
MJ
1020 }
1021
1022 for (cs = node->indirect_calls; cs; cs = cs->next_callee)
606d9a09 1023 ipa_compute_jump_functions_for_edge (parms_info, cs);
749aa96d
MJ
1024}
1025
6f7b8b70
RE
1026/* If RHS looks like a rhs of a statement loading pfn from a member
1027 pointer formal parameter, return the parameter, otherwise return
1028 NULL. If USE_DELTA, then we look for a use of the delta field
1029 rather than the pfn. */
be95e2b9 1030
3e293154 1031static tree
6f7b8b70 1032ipa_get_member_ptr_load_param (tree rhs, bool use_delta)
3e293154 1033{
ae788515 1034 tree rec, ref_field, ref_offset, fld, fld_offset, ptr_field, delta_field;
3e293154 1035
ae788515
EB
1036 if (TREE_CODE (rhs) == COMPONENT_REF)
1037 {
1038 ref_field = TREE_OPERAND (rhs, 1);
1039 rhs = TREE_OPERAND (rhs, 0);
1040 }
1041 else
1042 ref_field = NULL_TREE;
d242d063 1043 if (TREE_CODE (rhs) != MEM_REF)
3e293154 1044 return NULL_TREE;
3e293154 1045 rec = TREE_OPERAND (rhs, 0);
d242d063
MJ
1046 if (TREE_CODE (rec) != ADDR_EXPR)
1047 return NULL_TREE;
1048 rec = TREE_OPERAND (rec, 0);
3e293154 1049 if (TREE_CODE (rec) != PARM_DECL
6f7b8b70 1050 || !type_like_member_ptr_p (TREE_TYPE (rec), &ptr_field, &delta_field))
3e293154
MJ
1051 return NULL_TREE;
1052
d242d063 1053 ref_offset = TREE_OPERAND (rhs, 1);
ae788515
EB
1054
1055 if (ref_field)
1056 {
1057 if (integer_nonzerop (ref_offset))
1058 return NULL_TREE;
1059
1060 if (use_delta)
1061 fld = delta_field;
1062 else
1063 fld = ptr_field;
1064
1065 return ref_field == fld ? rec : NULL_TREE;
1066 }
1067
d242d063
MJ
1068 if (use_delta)
1069 fld_offset = byte_position (delta_field);
3e293154 1070 else
d242d063
MJ
1071 fld_offset = byte_position (ptr_field);
1072
1073 return tree_int_cst_equal (ref_offset, fld_offset) ? rec : NULL_TREE;
3e293154
MJ
1074}
1075
1076/* If STMT looks like a statement loading a value from a member pointer formal
be95e2b9
MJ
1077 parameter, this function returns that parameter. */
1078
3e293154 1079static tree
6f7b8b70 1080ipa_get_stmt_member_ptr_load_param (gimple stmt, bool use_delta)
3e293154
MJ
1081{
1082 tree rhs;
1083
8b75fc9b 1084 if (!gimple_assign_single_p (stmt))
3e293154
MJ
1085 return NULL_TREE;
1086
726a989a 1087 rhs = gimple_assign_rhs1 (stmt);
6f7b8b70 1088 return ipa_get_member_ptr_load_param (rhs, use_delta);
3e293154
MJ
1089}
1090
1091/* Returns true iff T is an SSA_NAME defined by a statement. */
be95e2b9 1092
3e293154
MJ
1093static bool
1094ipa_is_ssa_with_stmt_def (tree t)
1095{
1096 if (TREE_CODE (t) == SSA_NAME
1097 && !SSA_NAME_IS_DEFAULT_DEF (t))
1098 return true;
1099 else
1100 return false;
1101}
1102
40591473
MJ
1103/* Find the indirect call graph edge corresponding to STMT and mark it as a
1104 call to a parameter number PARAM_INDEX. NODE is the caller. Return the
1105 indirect call graph edge. */
be95e2b9 1106
40591473
MJ
1107static struct cgraph_edge *
1108ipa_note_param_call (struct cgraph_node *node, int param_index, gimple stmt)
3e293154 1109{
e33c6cd6 1110 struct cgraph_edge *cs;
3e293154 1111
5f902d76 1112 cs = cgraph_edge (node, stmt);
b258210c
MJ
1113 cs->indirect_info->param_index = param_index;
1114 cs->indirect_info->anc_offset = 0;
40591473
MJ
1115 cs->indirect_info->polymorphic = 0;
1116 return cs;
3e293154
MJ
1117}
1118
e33c6cd6 1119/* Analyze the CALL and examine uses of formal parameters of the caller NODE
062c604f
MJ
1120 (described by INFO). PARMS_INFO is a pointer to a vector containing
1121 intermediate information about each formal parameter. Currently it checks
1122 whether the call calls a pointer that is a formal parameter and if so, the
1123 parameter is marked with the called flag and an indirect call graph edge
1124 describing the call is created. This is very simple for ordinary pointers
1125 represented in SSA but not-so-nice when it comes to member pointers. The
1126 ugly part of this function does nothing more than trying to match the
1127 pattern of such a call. An example of such a pattern is the gimple dump
1128 below, the call is on the last line:
3e293154 1129
ae788515
EB
1130 <bb 2>:
1131 f$__delta_5 = f.__delta;
1132 f$__pfn_24 = f.__pfn;
1133
1134 or
3e293154 1135 <bb 2>:
d242d063
MJ
1136 f$__delta_5 = MEM[(struct *)&f];
1137 f$__pfn_24 = MEM[(struct *)&f + 4B];
8aa29647 1138
ae788515 1139 and a few lines below:
8aa29647
MJ
1140
1141 <bb 5>
3e293154
MJ
1142 D.2496_3 = (int) f$__pfn_24;
1143 D.2497_4 = D.2496_3 & 1;
1144 if (D.2497_4 != 0)
1145 goto <bb 3>;
1146 else
1147 goto <bb 4>;
1148
8aa29647 1149 <bb 6>:
3e293154
MJ
1150 D.2500_7 = (unsigned int) f$__delta_5;
1151 D.2501_8 = &S + D.2500_7;
1152 D.2502_9 = (int (*__vtbl_ptr_type) (void) * *) D.2501_8;
1153 D.2503_10 = *D.2502_9;
1154 D.2504_12 = f$__pfn_24 + -1;
1155 D.2505_13 = (unsigned int) D.2504_12;
1156 D.2506_14 = D.2503_10 + D.2505_13;
1157 D.2507_15 = *D.2506_14;
1158 iftmp.11_16 = (String:: *) D.2507_15;
1159
8aa29647 1160 <bb 7>:
3e293154
MJ
1161 # iftmp.11_1 = PHI <iftmp.11_16(3), f$__pfn_24(2)>
1162 D.2500_19 = (unsigned int) f$__delta_5;
1163 D.2508_20 = &S + D.2500_19;
1164 D.2493_21 = iftmp.11_1 (D.2508_20, 4);
1165
1166 Such patterns are results of simple calls to a member pointer:
1167
1168 int doprinting (int (MyString::* f)(int) const)
1169 {
1170 MyString S ("somestring");
1171
1172 return (S.*f)(4);
1173 }
1174*/
1175
1176static void
b258210c
MJ
1177ipa_analyze_indirect_call_uses (struct cgraph_node *node,
1178 struct ipa_node_params *info,
062c604f 1179 struct param_analysis_info *parms_info,
b258210c 1180 gimple call, tree target)
3e293154 1181{
726a989a 1182 gimple def;
3e293154 1183 tree n1, n2;
726a989a
RB
1184 gimple d1, d2;
1185 tree rec, rec2, cond;
1186 gimple branch;
3e293154 1187 int index;
3e293154
MJ
1188 basic_block bb, virt_bb, join;
1189
3e293154
MJ
1190 if (SSA_NAME_IS_DEFAULT_DEF (target))
1191 {
b258210c 1192 tree var = SSA_NAME_VAR (target);
3e293154
MJ
1193 index = ipa_get_param_decl_index (info, var);
1194 if (index >= 0)
40591473 1195 ipa_note_param_call (node, index, call);
3e293154
MJ
1196 return;
1197 }
1198
1199 /* Now we need to try to match the complex pattern of calling a member
1200 pointer. */
1201
1202 if (!POINTER_TYPE_P (TREE_TYPE (target))
1203 || TREE_CODE (TREE_TYPE (TREE_TYPE (target))) != METHOD_TYPE)
1204 return;
1205
1206 def = SSA_NAME_DEF_STMT (target);
726a989a 1207 if (gimple_code (def) != GIMPLE_PHI)
3e293154
MJ
1208 return;
1209
726a989a 1210 if (gimple_phi_num_args (def) != 2)
3e293154
MJ
1211 return;
1212
1213 /* First, we need to check whether one of these is a load from a member
1214 pointer that is a parameter to this function. */
1215 n1 = PHI_ARG_DEF (def, 0);
1216 n2 = PHI_ARG_DEF (def, 1);
1fc8feb5 1217 if (!ipa_is_ssa_with_stmt_def (n1) || !ipa_is_ssa_with_stmt_def (n2))
3e293154
MJ
1218 return;
1219 d1 = SSA_NAME_DEF_STMT (n1);
1220 d2 = SSA_NAME_DEF_STMT (n2);
1221
8aa29647 1222 join = gimple_bb (def);
6f7b8b70 1223 if ((rec = ipa_get_stmt_member_ptr_load_param (d1, false)))
3e293154 1224 {
6f7b8b70 1225 if (ipa_get_stmt_member_ptr_load_param (d2, false))
3e293154
MJ
1226 return;
1227
8aa29647 1228 bb = EDGE_PRED (join, 0)->src;
726a989a 1229 virt_bb = gimple_bb (d2);
3e293154 1230 }
6f7b8b70 1231 else if ((rec = ipa_get_stmt_member_ptr_load_param (d2, false)))
3e293154 1232 {
8aa29647 1233 bb = EDGE_PRED (join, 1)->src;
726a989a 1234 virt_bb = gimple_bb (d1);
3e293154
MJ
1235 }
1236 else
1237 return;
1238
1239 /* Second, we need to check that the basic blocks are laid out in the way
1240 corresponding to the pattern. */
1241
3e293154
MJ
1242 if (!single_pred_p (virt_bb) || !single_succ_p (virt_bb)
1243 || single_pred (virt_bb) != bb
1244 || single_succ (virt_bb) != join)
1245 return;
1246
1247 /* Third, let's see that the branching is done depending on the least
1248 significant bit of the pfn. */
1249
1250 branch = last_stmt (bb);
8aa29647 1251 if (!branch || gimple_code (branch) != GIMPLE_COND)
3e293154
MJ
1252 return;
1253
12430896
RG
1254 if ((gimple_cond_code (branch) != NE_EXPR
1255 && gimple_cond_code (branch) != EQ_EXPR)
726a989a 1256 || !integer_zerop (gimple_cond_rhs (branch)))
3e293154 1257 return;
3e293154 1258
726a989a 1259 cond = gimple_cond_lhs (branch);
3e293154
MJ
1260 if (!ipa_is_ssa_with_stmt_def (cond))
1261 return;
1262
726a989a 1263 def = SSA_NAME_DEF_STMT (cond);
8b75fc9b 1264 if (!is_gimple_assign (def)
726a989a
RB
1265 || gimple_assign_rhs_code (def) != BIT_AND_EXPR
1266 || !integer_onep (gimple_assign_rhs2 (def)))
3e293154 1267 return;
726a989a
RB
1268
1269 cond = gimple_assign_rhs1 (def);
3e293154
MJ
1270 if (!ipa_is_ssa_with_stmt_def (cond))
1271 return;
1272
726a989a 1273 def = SSA_NAME_DEF_STMT (cond);
3e293154 1274
8b75fc9b
MJ
1275 if (is_gimple_assign (def)
1276 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
3e293154 1277 {
726a989a 1278 cond = gimple_assign_rhs1 (def);
3e293154
MJ
1279 if (!ipa_is_ssa_with_stmt_def (cond))
1280 return;
726a989a 1281 def = SSA_NAME_DEF_STMT (cond);
3e293154
MJ
1282 }
1283
6f7b8b70
RE
1284 rec2 = ipa_get_stmt_member_ptr_load_param (def,
1285 (TARGET_PTRMEMFUNC_VBIT_LOCATION
1286 == ptrmemfunc_vbit_in_delta));
1287
3e293154
MJ
1288 if (rec != rec2)
1289 return;
1290
1291 index = ipa_get_param_decl_index (info, rec);
062c604f
MJ
1292 if (index >= 0 && !is_parm_modified_before_call (&parms_info[index],
1293 call, rec))
40591473 1294 ipa_note_param_call (node, index, call);
3e293154
MJ
1295
1296 return;
1297}
1298
b258210c
MJ
1299/* Analyze a CALL to an OBJ_TYPE_REF which is passed in TARGET and if the
1300 object referenced in the expression is a formal parameter of the caller
1301 (described by INFO), create a call note for the statement. */
1302
1303static void
1304ipa_analyze_virtual_call_uses (struct cgraph_node *node,
1305 struct ipa_node_params *info, gimple call,
1306 tree target)
1307{
40591473
MJ
1308 struct cgraph_edge *cs;
1309 struct cgraph_indirect_call_info *ii;
f65cf2b7 1310 struct ipa_jump_func jfunc;
b258210c 1311 tree obj = OBJ_TYPE_REF_OBJECT (target);
b258210c 1312 int index;
40591473 1313 HOST_WIDE_INT anc_offset;
b258210c 1314
05842ff5
MJ
1315 if (!flag_devirtualize)
1316 return;
1317
40591473 1318 if (TREE_CODE (obj) != SSA_NAME)
b258210c
MJ
1319 return;
1320
40591473
MJ
1321 if (SSA_NAME_IS_DEFAULT_DEF (obj))
1322 {
1323 if (TREE_CODE (SSA_NAME_VAR (obj)) != PARM_DECL)
1324 return;
b258210c 1325
40591473
MJ
1326 anc_offset = 0;
1327 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (obj));
1328 gcc_assert (index >= 0);
1329 if (detect_type_change_ssa (obj, call, &jfunc))
1330 return;
1331 }
1332 else
1333 {
1334 gimple stmt = SSA_NAME_DEF_STMT (obj);
1335 tree expr;
1336
1337 expr = get_ancestor_addr_info (stmt, &obj, &anc_offset);
1338 if (!expr)
1339 return;
1340 index = ipa_get_param_decl_index (info,
1341 SSA_NAME_VAR (TREE_OPERAND (expr, 0)));
1342 gcc_assert (index >= 0);
1343 if (detect_type_change (obj, expr, call, &jfunc, anc_offset))
1344 return;
1345 }
1346
1347 cs = ipa_note_param_call (node, index, call);
1348 ii = cs->indirect_info;
1349 ii->anc_offset = anc_offset;
1350 ii->otr_token = tree_low_cst (OBJ_TYPE_REF_TOKEN (target), 1);
1351 ii->otr_type = TREE_TYPE (TREE_TYPE (OBJ_TYPE_REF_OBJECT (target)));
1352 ii->polymorphic = 1;
b258210c
MJ
1353}
1354
1355/* Analyze a call statement CALL whether and how it utilizes formal parameters
062c604f
MJ
1356 of the caller (described by INFO). PARMS_INFO is a pointer to a vector
1357 containing intermediate information about each formal parameter. */
b258210c
MJ
1358
1359static void
1360ipa_analyze_call_uses (struct cgraph_node *node,
062c604f
MJ
1361 struct ipa_node_params *info,
1362 struct param_analysis_info *parms_info, gimple call)
b258210c
MJ
1363{
1364 tree target = gimple_call_fn (call);
1365
25583c4f
RS
1366 if (!target)
1367 return;
b258210c 1368 if (TREE_CODE (target) == SSA_NAME)
062c604f 1369 ipa_analyze_indirect_call_uses (node, info, parms_info, call, target);
b258210c
MJ
1370 else if (TREE_CODE (target) == OBJ_TYPE_REF)
1371 ipa_analyze_virtual_call_uses (node, info, call, target);
1372}
1373
1374
e33c6cd6
MJ
1375/* Analyze the call statement STMT with respect to formal parameters (described
1376 in INFO) of caller given by NODE. Currently it only checks whether formal
062c604f
MJ
1377 parameters are called. PARMS_INFO is a pointer to a vector containing
1378 intermediate information about each formal parameter. */
be95e2b9 1379
3e293154 1380static void
e33c6cd6 1381ipa_analyze_stmt_uses (struct cgraph_node *node, struct ipa_node_params *info,
062c604f 1382 struct param_analysis_info *parms_info, gimple stmt)
3e293154 1383{
726a989a 1384 if (is_gimple_call (stmt))
062c604f
MJ
1385 ipa_analyze_call_uses (node, info, parms_info, stmt);
1386}
1387
1388/* Callback of walk_stmt_load_store_addr_ops for the visit_load.
1389 If OP is a parameter declaration, mark it as used in the info structure
1390 passed in DATA. */
1391
1392static bool
1393visit_ref_for_mod_analysis (gimple stmt ATTRIBUTE_UNUSED,
1394 tree op, void *data)
1395{
1396 struct ipa_node_params *info = (struct ipa_node_params *) data;
1397
1398 op = get_base_address (op);
1399 if (op
1400 && TREE_CODE (op) == PARM_DECL)
1401 {
1402 int index = ipa_get_param_decl_index (info, op);
1403 gcc_assert (index >= 0);
310bc633 1404 ipa_set_param_used (info, index, true);
062c604f
MJ
1405 }
1406
1407 return false;
3e293154
MJ
1408}
1409
1410/* Scan the function body of NODE and inspect the uses of formal parameters.
1411 Store the findings in various structures of the associated ipa_node_params
062c604f
MJ
1412 structure, such as parameter flags, notes etc. PARMS_INFO is a pointer to a
1413 vector containing intermediate information about each formal parameter. */
be95e2b9 1414
062c604f
MJ
1415static void
1416ipa_analyze_params_uses (struct cgraph_node *node,
1417 struct param_analysis_info *parms_info)
3e293154
MJ
1418{
1419 tree decl = node->decl;
1420 basic_block bb;
1421 struct function *func;
726a989a 1422 gimple_stmt_iterator gsi;
3e293154 1423 struct ipa_node_params *info = IPA_NODE_REF (node);
062c604f 1424 int i;
3e293154 1425
726a989a 1426 if (ipa_get_param_count (info) == 0 || info->uses_analysis_done)
3e293154 1427 return;
3e293154 1428
062c604f
MJ
1429 for (i = 0; i < ipa_get_param_count (info); i++)
1430 {
1431 tree parm = ipa_get_param (info, i);
1432 /* For SSA regs see if parameter is used. For non-SSA we compute
1433 the flag during modification analysis. */
1434 if (is_gimple_reg (parm)
1435 && gimple_default_def (DECL_STRUCT_FUNCTION (node->decl), parm))
310bc633 1436 ipa_set_param_used (info, i, true);
062c604f
MJ
1437 }
1438
3e293154
MJ
1439 func = DECL_STRUCT_FUNCTION (decl);
1440 FOR_EACH_BB_FN (bb, func)
1441 {
726a989a 1442 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3e293154 1443 {
726a989a 1444 gimple stmt = gsi_stmt (gsi);
062c604f
MJ
1445
1446 if (is_gimple_debug (stmt))
1447 continue;
1448
1449 ipa_analyze_stmt_uses (node, info, parms_info, stmt);
1450 walk_stmt_load_store_addr_ops (stmt, info,
1451 visit_ref_for_mod_analysis,
1452 visit_ref_for_mod_analysis,
1453 visit_ref_for_mod_analysis);
518dc859 1454 }
062c604f
MJ
1455 for (gsi = gsi_start (phi_nodes (bb)); !gsi_end_p (gsi); gsi_next (&gsi))
1456 walk_stmt_load_store_addr_ops (gsi_stmt (gsi), info,
1457 visit_ref_for_mod_analysis,
1458 visit_ref_for_mod_analysis,
1459 visit_ref_for_mod_analysis);
518dc859 1460 }
3e293154
MJ
1461
1462 info->uses_analysis_done = 1;
1463}
1464
dd5a833e
MS
1465/* Initialize the array describing properties of of formal parameters
1466 of NODE, analyze their uses and compute jump functions associated
1467 with actual arguments of calls from within NODE. */
062c604f
MJ
1468
1469void
1470ipa_analyze_node (struct cgraph_node *node)
1471{
57dbdc5a 1472 struct ipa_node_params *info;
062c604f
MJ
1473 struct param_analysis_info *parms_info;
1474 int i, param_count;
1475
57dbdc5a
MJ
1476 ipa_check_create_node_params ();
1477 ipa_check_create_edge_args ();
1478 info = IPA_NODE_REF (node);
f65cf2b7
MJ
1479 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
1480 current_function_decl = node->decl;
062c604f
MJ
1481 ipa_initialize_node_params (node);
1482
1483 param_count = ipa_get_param_count (info);
1484 parms_info = XALLOCAVEC (struct param_analysis_info, param_count);
1485 memset (parms_info, 0, sizeof (struct param_analysis_info) * param_count);
1486
1487 ipa_analyze_params_uses (node, parms_info);
1488 ipa_compute_jump_functions (node, parms_info);
1489
1490 for (i = 0; i < param_count; i++)
1491 if (parms_info[i].visited_statements)
1492 BITMAP_FREE (parms_info[i].visited_statements);
f65cf2b7
MJ
1493
1494 current_function_decl = NULL;
1495 pop_cfun ();
062c604f
MJ
1496}
1497
1498
61502ca8 1499/* Update the jump function DST when the call graph edge corresponding to SRC is
b258210c
MJ
1500 is being inlined, knowing that DST is of type ancestor and src of known
1501 type. */
1502
1503static void
1504combine_known_type_and_ancestor_jfs (struct ipa_jump_func *src,
1505 struct ipa_jump_func *dst)
1506{
1507 tree new_binfo;
1508
1509 new_binfo = get_binfo_at_offset (src->value.base_binfo,
1510 dst->value.ancestor.offset,
1511 dst->value.ancestor.type);
1512 if (new_binfo)
1513 {
1514 dst->type = IPA_JF_KNOWN_TYPE;
1515 dst->value.base_binfo = new_binfo;
1516 }
1517 else
1518 dst->type = IPA_JF_UNKNOWN;
1519}
1520
be95e2b9 1521/* Update the jump functions associated with call graph edge E when the call
3e293154 1522 graph edge CS is being inlined, assuming that E->caller is already (possibly
b258210c 1523 indirectly) inlined into CS->callee and that E has not been inlined. */
be95e2b9 1524
3e293154
MJ
1525static void
1526update_jump_functions_after_inlining (struct cgraph_edge *cs,
1527 struct cgraph_edge *e)
1528{
1529 struct ipa_edge_args *top = IPA_EDGE_REF (cs);
1530 struct ipa_edge_args *args = IPA_EDGE_REF (e);
1531 int count = ipa_get_cs_argument_count (args);
1532 int i;
1533
1534 for (i = 0; i < count; i++)
1535 {
b258210c 1536 struct ipa_jump_func *dst = ipa_get_ith_jump_func (args, i);
3e293154 1537
685b0d13
MJ
1538 if (dst->type == IPA_JF_ANCESTOR)
1539 {
b258210c 1540 struct ipa_jump_func *src;
685b0d13 1541
b258210c
MJ
1542 /* Variable number of arguments can cause havoc if we try to access
1543 one that does not exist in the inlined edge. So make sure we
1544 don't. */
1545 if (dst->value.ancestor.formal_id >= ipa_get_cs_argument_count (top))
1546 {
1547 dst->type = IPA_JF_UNKNOWN;
1548 continue;
1549 }
1550
1551 src = ipa_get_ith_jump_func (top, dst->value.ancestor.formal_id);
1552 if (src->type == IPA_JF_KNOWN_TYPE)
1553 combine_known_type_and_ancestor_jfs (src, dst);
b258210c
MJ
1554 else if (src->type == IPA_JF_PASS_THROUGH
1555 && src->value.pass_through.operation == NOP_EXPR)
1556 dst->value.ancestor.formal_id = src->value.pass_through.formal_id;
1557 else if (src->type == IPA_JF_ANCESTOR)
1558 {
1559 dst->value.ancestor.formal_id = src->value.ancestor.formal_id;
1560 dst->value.ancestor.offset += src->value.ancestor.offset;
1561 }
1562 else
1563 dst->type = IPA_JF_UNKNOWN;
1564 }
1565 else if (dst->type == IPA_JF_PASS_THROUGH)
3e293154 1566 {
b258210c
MJ
1567 struct ipa_jump_func *src;
1568 /* We must check range due to calls with variable number of arguments
1569 and we cannot combine jump functions with operations. */
1570 if (dst->value.pass_through.operation == NOP_EXPR
1571 && (dst->value.pass_through.formal_id
1572 < ipa_get_cs_argument_count (top)))
1573 {
1574 src = ipa_get_ith_jump_func (top,
1575 dst->value.pass_through.formal_id);
1576 *dst = *src;
1577 }
1578 else
1579 dst->type = IPA_JF_UNKNOWN;
3e293154 1580 }
b258210c
MJ
1581 }
1582}
1583
1584/* If TARGET is an addr_expr of a function declaration, make it the destination
81fa35bd 1585 of an indirect edge IE and return the edge. Otherwise, return NULL. */
b258210c 1586
3949c4a7 1587struct cgraph_edge *
81fa35bd 1588ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target)
b258210c
MJ
1589{
1590 struct cgraph_node *callee;
1591
ceeffab0
MJ
1592 if (TREE_CODE (target) == ADDR_EXPR)
1593 target = TREE_OPERAND (target, 0);
b258210c
MJ
1594 if (TREE_CODE (target) != FUNCTION_DECL)
1595 return NULL;
581985d7 1596 callee = cgraph_get_node (target);
b258210c
MJ
1597 if (!callee)
1598 return NULL;
1dbee8c9 1599 ipa_check_create_node_params ();
ceeffab0 1600
81fa35bd
MJ
1601 /* We can not make edges to inline clones. It is bug that someone removed
1602 the cgraph node too early. */
17afc0fe
JH
1603 gcc_assert (!callee->global.inlined_to);
1604
81fa35bd 1605 cgraph_make_edge_direct (ie, callee);
b258210c
MJ
1606 if (dump_file)
1607 {
1608 fprintf (dump_file, "ipa-prop: Discovered %s call to a known target "
ceeffab0 1609 "(%s/%i -> %s/%i), for stmt ",
b258210c
MJ
1610 ie->indirect_info->polymorphic ? "a virtual" : "an indirect",
1611 cgraph_node_name (ie->caller), ie->caller->uid,
1612 cgraph_node_name (ie->callee), ie->callee->uid);
b258210c
MJ
1613 if (ie->call_stmt)
1614 print_gimple_stmt (dump_file, ie->call_stmt, 2, TDF_SLIM);
1615 else
1616 fprintf (dump_file, "with uid %i\n", ie->lto_stmt_uid);
3e293154 1617 }
380ed5ed 1618 callee = cgraph_function_or_thunk_node (callee, NULL);
749aa96d 1619
b258210c 1620 return ie;
3e293154
MJ
1621}
1622
b258210c
MJ
1623/* Try to find a destination for indirect edge IE that corresponds to a simple
1624 call or a call of a member function pointer and where the destination is a
1625 pointer formal parameter described by jump function JFUNC. If it can be
1626 determined, return the newly direct edge, otherwise return NULL. */
be95e2b9 1627
b258210c
MJ
1628static struct cgraph_edge *
1629try_make_edge_direct_simple_call (struct cgraph_edge *ie,
1630 struct ipa_jump_func *jfunc)
1631{
1632 tree target;
1633
1634 if (jfunc->type == IPA_JF_CONST)
1635 target = jfunc->value.constant;
1636 else if (jfunc->type == IPA_JF_CONST_MEMBER_PTR)
1637 target = jfunc->value.member_cst.pfn;
1638 else
1639 return NULL;
1640
81fa35bd 1641 return ipa_make_edge_direct_to_target (ie, target);
b258210c
MJ
1642}
1643
1644/* Try to find a destination for indirect edge IE that corresponds to a
61502ca8 1645 virtual call based on a formal parameter which is described by jump
b258210c
MJ
1646 function JFUNC and if it can be determined, make it direct and return the
1647 direct edge. Otherwise, return NULL. */
1648
1649static struct cgraph_edge *
1650try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
1651 struct ipa_jump_func *jfunc)
3e293154 1652{
81fa35bd 1653 tree binfo, type, target;
b258210c
MJ
1654 HOST_WIDE_INT token;
1655
1656 if (jfunc->type == IPA_JF_KNOWN_TYPE)
1657 binfo = jfunc->value.base_binfo;
3e293154 1658 else
b258210c
MJ
1659 return NULL;
1660
1661 if (!binfo)
1662 return NULL;
3e293154 1663
b258210c
MJ
1664 token = ie->indirect_info->otr_token;
1665 type = ie->indirect_info->otr_type;
1666 binfo = get_binfo_at_offset (binfo, ie->indirect_info->anc_offset, type);
1667 if (binfo)
81fa35bd 1668 target = gimple_get_virt_method_for_binfo (token, binfo);
b258210c
MJ
1669 else
1670 return NULL;
1671
1672 if (target)
81fa35bd 1673 return ipa_make_edge_direct_to_target (ie, target);
b258210c
MJ
1674 else
1675 return NULL;
3e293154
MJ
1676}
1677
1678/* Update the param called notes associated with NODE when CS is being inlined,
1679 assuming NODE is (potentially indirectly) inlined into CS->callee.
1680 Moreover, if the callee is discovered to be constant, create a new cgraph
e56f5f3e 1681 edge for it. Newly discovered indirect edges will be added to *NEW_EDGES,
f8e2a1ed 1682 unless NEW_EDGES is NULL. Return true iff a new edge(s) were created. */
be95e2b9 1683
f8e2a1ed 1684static bool
e33c6cd6
MJ
1685update_indirect_edges_after_inlining (struct cgraph_edge *cs,
1686 struct cgraph_node *node,
1687 VEC (cgraph_edge_p, heap) **new_edges)
3e293154 1688{
9e97ff61 1689 struct ipa_edge_args *top;
b258210c 1690 struct cgraph_edge *ie, *next_ie, *new_direct_edge;
f8e2a1ed 1691 bool res = false;
3e293154 1692
e33c6cd6 1693 ipa_check_create_edge_args ();
9e97ff61 1694 top = IPA_EDGE_REF (cs);
e33c6cd6
MJ
1695
1696 for (ie = node->indirect_calls; ie; ie = next_ie)
3e293154 1697 {
e33c6cd6 1698 struct cgraph_indirect_call_info *ici = ie->indirect_info;
3e293154
MJ
1699 struct ipa_jump_func *jfunc;
1700
e33c6cd6
MJ
1701 next_ie = ie->next_callee;
1702 if (bitmap_bit_p (iinlining_processed_edges, ie->uid))
3e293154
MJ
1703 continue;
1704
e33c6cd6
MJ
1705 /* If we ever use indirect edges for anything other than indirect
1706 inlining, we will need to skip those with negative param_indices. */
5f902d76
JH
1707 if (ici->param_index == -1)
1708 continue;
e33c6cd6 1709
3e293154 1710 /* We must check range due to calls with variable number of arguments: */
e33c6cd6 1711 if (ici->param_index >= ipa_get_cs_argument_count (top))
3e293154 1712 {
e33c6cd6 1713 bitmap_set_bit (iinlining_processed_edges, ie->uid);
3e293154
MJ
1714 continue;
1715 }
1716
e33c6cd6 1717 jfunc = ipa_get_ith_jump_func (top, ici->param_index);
685b0d13
MJ
1718 if (jfunc->type == IPA_JF_PASS_THROUGH
1719 && jfunc->value.pass_through.operation == NOP_EXPR)
e33c6cd6 1720 ici->param_index = jfunc->value.pass_through.formal_id;
b258210c 1721 else if (jfunc->type == IPA_JF_ANCESTOR)
3e293154 1722 {
b258210c
MJ
1723 ici->param_index = jfunc->value.ancestor.formal_id;
1724 ici->anc_offset += jfunc->value.ancestor.offset;
3e293154 1725 }
685b0d13 1726 else
b258210c
MJ
1727 /* Either we can find a destination for this edge now or never. */
1728 bitmap_set_bit (iinlining_processed_edges, ie->uid);
1729
1730 if (ici->polymorphic)
1731 new_direct_edge = try_make_edge_direct_virtual_call (ie, jfunc);
1732 else
1733 new_direct_edge = try_make_edge_direct_simple_call (ie, jfunc);
1734
1735 if (new_direct_edge)
685b0d13 1736 {
b258210c
MJ
1737 new_direct_edge->indirect_inlining_edge = 1;
1738 if (new_edges)
1739 {
1740 VEC_safe_push (cgraph_edge_p, heap, *new_edges,
1741 new_direct_edge);
1742 top = IPA_EDGE_REF (cs);
1743 res = true;
1744 }
685b0d13 1745 }
3e293154 1746 }
e33c6cd6 1747
f8e2a1ed 1748 return res;
3e293154
MJ
1749}
1750
1751/* Recursively traverse subtree of NODE (including node) made of inlined
1752 cgraph_edges when CS has been inlined and invoke
e33c6cd6 1753 update_indirect_edges_after_inlining on all nodes and
3e293154
MJ
1754 update_jump_functions_after_inlining on all non-inlined edges that lead out
1755 of this subtree. Newly discovered indirect edges will be added to
f8e2a1ed
MJ
1756 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were
1757 created. */
be95e2b9 1758
f8e2a1ed 1759static bool
3e293154
MJ
1760propagate_info_to_inlined_callees (struct cgraph_edge *cs,
1761 struct cgraph_node *node,
e56f5f3e 1762 VEC (cgraph_edge_p, heap) **new_edges)
3e293154
MJ
1763{
1764 struct cgraph_edge *e;
f8e2a1ed 1765 bool res;
3e293154 1766
e33c6cd6 1767 res = update_indirect_edges_after_inlining (cs, node, new_edges);
3e293154
MJ
1768
1769 for (e = node->callees; e; e = e->next_callee)
1770 if (!e->inline_failed)
f8e2a1ed 1771 res |= propagate_info_to_inlined_callees (cs, e->callee, new_edges);
3e293154
MJ
1772 else
1773 update_jump_functions_after_inlining (cs, e);
f8e2a1ed
MJ
1774
1775 return res;
3e293154
MJ
1776}
1777
1778/* Update jump functions and call note functions on inlining the call site CS.
1779 CS is expected to lead to a node already cloned by
1780 cgraph_clone_inline_nodes. Newly discovered indirect edges will be added to
f8e2a1ed
MJ
1781 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were +
1782 created. */
be95e2b9 1783
f8e2a1ed 1784bool
3e293154 1785ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
e56f5f3e 1786 VEC (cgraph_edge_p, heap) **new_edges)
3e293154 1787{
f8e2a1ed
MJ
1788 /* Do nothing if the preparation phase has not been carried out yet
1789 (i.e. during early inlining). */
1790 if (!ipa_node_params_vector)
1791 return false;
1792 gcc_assert (ipa_edge_args_vector);
1793
1794 return propagate_info_to_inlined_callees (cs, cs->callee, new_edges);
518dc859
RL
1795}
1796
771578a0
MJ
1797/* Frees all dynamically allocated structures that the argument info points
1798 to. */
be95e2b9 1799
518dc859 1800void
771578a0 1801ipa_free_edge_args_substructures (struct ipa_edge_args *args)
518dc859 1802{
771578a0 1803 if (args->jump_functions)
fb3f88cc 1804 ggc_free (args->jump_functions);
771578a0
MJ
1805
1806 memset (args, 0, sizeof (*args));
518dc859
RL
1807}
1808
771578a0 1809/* Free all ipa_edge structures. */
be95e2b9 1810
518dc859 1811void
771578a0 1812ipa_free_all_edge_args (void)
518dc859 1813{
771578a0
MJ
1814 int i;
1815 struct ipa_edge_args *args;
518dc859 1816
ac47786e 1817 FOR_EACH_VEC_ELT (ipa_edge_args_t, ipa_edge_args_vector, i, args)
771578a0
MJ
1818 ipa_free_edge_args_substructures (args);
1819
fb3f88cc 1820 VEC_free (ipa_edge_args_t, gc, ipa_edge_args_vector);
771578a0 1821 ipa_edge_args_vector = NULL;
518dc859
RL
1822}
1823
771578a0
MJ
1824/* Frees all dynamically allocated structures that the param info points
1825 to. */
be95e2b9 1826
518dc859 1827void
771578a0 1828ipa_free_node_params_substructures (struct ipa_node_params *info)
518dc859 1829{
310bc633
MJ
1830 VEC_free (ipa_param_descriptor_t, heap, info->descriptors);
1831 free (info->lattices);
1832 /* Lattice values and their sources are deallocated with their alocation
1833 pool. */
1834 VEC_free (tree, heap, info->known_vals);
771578a0 1835 memset (info, 0, sizeof (*info));
518dc859
RL
1836}
1837
771578a0 1838/* Free all ipa_node_params structures. */
be95e2b9 1839
518dc859 1840void
771578a0 1841ipa_free_all_node_params (void)
518dc859 1842{
771578a0
MJ
1843 int i;
1844 struct ipa_node_params *info;
518dc859 1845
ac47786e 1846 FOR_EACH_VEC_ELT (ipa_node_params_t, ipa_node_params_vector, i, info)
771578a0
MJ
1847 ipa_free_node_params_substructures (info);
1848
1849 VEC_free (ipa_node_params_t, heap, ipa_node_params_vector);
1850 ipa_node_params_vector = NULL;
1851}
1852
1853/* Hook that is called by cgraph.c when an edge is removed. */
be95e2b9 1854
771578a0 1855static void
5c0466b5 1856ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
771578a0 1857{
c6f7cfc1
JH
1858 /* During IPA-CP updating we can be called on not-yet analyze clones. */
1859 if (VEC_length (ipa_edge_args_t, ipa_edge_args_vector)
1860 <= (unsigned)cs->uid)
1861 return;
771578a0 1862 ipa_free_edge_args_substructures (IPA_EDGE_REF (cs));
518dc859
RL
1863}
1864
771578a0 1865/* Hook that is called by cgraph.c when a node is removed. */
be95e2b9 1866
771578a0 1867static void
5c0466b5 1868ipa_node_removal_hook (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
771578a0 1869{
dd6d1ad7
JH
1870 /* During IPA-CP updating we can be called on not-yet analyze clones. */
1871 if (VEC_length (ipa_node_params_t, ipa_node_params_vector)
1872 <= (unsigned)node->uid)
1873 return;
771578a0
MJ
1874 ipa_free_node_params_substructures (IPA_NODE_REF (node));
1875}
1876
771578a0 1877/* Hook that is called by cgraph.c when a node is duplicated. */
be95e2b9 1878
771578a0
MJ
1879static void
1880ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
f8e2a1ed 1881 __attribute__((unused)) void *data)
771578a0
MJ
1882{
1883 struct ipa_edge_args *old_args, *new_args;
771578a0
MJ
1884
1885 ipa_check_create_edge_args ();
1886
1887 old_args = IPA_EDGE_REF (src);
1888 new_args = IPA_EDGE_REF (dst);
1889
606d9a09
MJ
1890 new_args->jump_functions = VEC_copy (ipa_jump_func_t, gc,
1891 old_args->jump_functions);
e33c6cd6
MJ
1892
1893 if (iinlining_processed_edges
1894 && bitmap_bit_p (iinlining_processed_edges, src->uid))
1895 bitmap_set_bit (iinlining_processed_edges, dst->uid);
771578a0
MJ
1896}
1897
1898/* Hook that is called by cgraph.c when a node is duplicated. */
be95e2b9 1899
771578a0
MJ
1900static void
1901ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
10a5dd5d 1902 ATTRIBUTE_UNUSED void *data)
771578a0
MJ
1903{
1904 struct ipa_node_params *old_info, *new_info;
771578a0
MJ
1905
1906 ipa_check_create_node_params ();
1907 old_info = IPA_NODE_REF (src);
1908 new_info = IPA_NODE_REF (dst);
771578a0 1909
310bc633
MJ
1910 new_info->descriptors = VEC_copy (ipa_param_descriptor_t, heap,
1911 old_info->descriptors);
1912 new_info->lattices = NULL;
771578a0 1913 new_info->ipcp_orig_node = old_info->ipcp_orig_node;
3949c4a7 1914
3949c4a7
MJ
1915 new_info->uses_analysis_done = old_info->uses_analysis_done;
1916 new_info->node_enqueued = old_info->node_enqueued;
771578a0
MJ
1917}
1918
40982661
JH
1919
1920/* Analyze newly added function into callgraph. */
1921
1922static void
1923ipa_add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
1924{
1925 ipa_analyze_node (node);
1926}
1927
771578a0 1928/* Register our cgraph hooks if they are not already there. */
be95e2b9 1929
518dc859 1930void
771578a0 1931ipa_register_cgraph_hooks (void)
518dc859 1932{
771578a0
MJ
1933 if (!edge_removal_hook_holder)
1934 edge_removal_hook_holder =
1935 cgraph_add_edge_removal_hook (&ipa_edge_removal_hook, NULL);
1936 if (!node_removal_hook_holder)
1937 node_removal_hook_holder =
1938 cgraph_add_node_removal_hook (&ipa_node_removal_hook, NULL);
1939 if (!edge_duplication_hook_holder)
1940 edge_duplication_hook_holder =
1941 cgraph_add_edge_duplication_hook (&ipa_edge_duplication_hook, NULL);
1942 if (!node_duplication_hook_holder)
1943 node_duplication_hook_holder =
1944 cgraph_add_node_duplication_hook (&ipa_node_duplication_hook, NULL);
40982661
JH
1945 function_insertion_hook_holder =
1946 cgraph_add_function_insertion_hook (&ipa_add_new_function, NULL);
771578a0 1947}
518dc859 1948
771578a0 1949/* Unregister our cgraph hooks if they are not already there. */
be95e2b9 1950
771578a0
MJ
1951static void
1952ipa_unregister_cgraph_hooks (void)
1953{
1954 cgraph_remove_edge_removal_hook (edge_removal_hook_holder);
1955 edge_removal_hook_holder = NULL;
1956 cgraph_remove_node_removal_hook (node_removal_hook_holder);
1957 node_removal_hook_holder = NULL;
1958 cgraph_remove_edge_duplication_hook (edge_duplication_hook_holder);
1959 edge_duplication_hook_holder = NULL;
1960 cgraph_remove_node_duplication_hook (node_duplication_hook_holder);
1961 node_duplication_hook_holder = NULL;
40982661
JH
1962 cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
1963 function_insertion_hook_holder = NULL;
771578a0
MJ
1964}
1965
61502ca8 1966/* Allocate all necessary data structures necessary for indirect inlining. */
e33c6cd6
MJ
1967
1968void
1969ipa_create_all_structures_for_iinln (void)
1970{
1971 iinlining_processed_edges = BITMAP_ALLOC (NULL);
1972}
1973
771578a0
MJ
1974/* Free all ipa_node_params and all ipa_edge_args structures if they are no
1975 longer needed after ipa-cp. */
be95e2b9 1976
771578a0 1977void
e33c6cd6 1978ipa_free_all_structures_after_ipa_cp (void)
3e293154 1979{
7e8b322a 1980 if (!flag_indirect_inlining)
3e293154
MJ
1981 {
1982 ipa_free_all_edge_args ();
1983 ipa_free_all_node_params ();
310bc633
MJ
1984 free_alloc_pool (ipcp_sources_pool);
1985 free_alloc_pool (ipcp_values_pool);
3e293154
MJ
1986 ipa_unregister_cgraph_hooks ();
1987 }
1988}
1989
1990/* Free all ipa_node_params and all ipa_edge_args structures if they are no
1991 longer needed after indirect inlining. */
be95e2b9 1992
3e293154 1993void
e33c6cd6 1994ipa_free_all_structures_after_iinln (void)
771578a0 1995{
e33c6cd6
MJ
1996 BITMAP_FREE (iinlining_processed_edges);
1997
771578a0
MJ
1998 ipa_free_all_edge_args ();
1999 ipa_free_all_node_params ();
2000 ipa_unregister_cgraph_hooks ();
310bc633
MJ
2001 if (ipcp_sources_pool)
2002 free_alloc_pool (ipcp_sources_pool);
2003 if (ipcp_values_pool)
2004 free_alloc_pool (ipcp_values_pool);
518dc859
RL
2005}
2006
dcd416e3 2007/* Print ipa_tree_map data structures of all functions in the
518dc859 2008 callgraph to F. */
be95e2b9 2009
518dc859 2010void
ca30a539 2011ipa_print_node_params (FILE * f, struct cgraph_node *node)
518dc859
RL
2012{
2013 int i, count;
2014 tree temp;
3e293154 2015 struct ipa_node_params *info;
518dc859 2016
3e293154
MJ
2017 if (!node->analyzed)
2018 return;
2019 info = IPA_NODE_REF (node);
b258210c
MJ
2020 fprintf (f, " function %s parameter descriptors:\n",
2021 cgraph_node_name (node));
3e293154
MJ
2022 count = ipa_get_param_count (info);
2023 for (i = 0; i < count; i++)
518dc859 2024 {
f8e2a1ed 2025 temp = ipa_get_param (info, i);
ca30a539
JH
2026 if (TREE_CODE (temp) == PARM_DECL)
2027 fprintf (f, " param %d : %s", i,
90e1a349
MH
2028 (DECL_NAME (temp)
2029 ? (*lang_hooks.decl_printable_name) (temp, 2)
2030 : "(unnamed)"));
339f49ec
JH
2031 if (ipa_is_param_used (info, i))
2032 fprintf (f, " used");
3e293154 2033 fprintf (f, "\n");
518dc859
RL
2034 }
2035}
dcd416e3 2036
ca30a539 2037/* Print ipa_tree_map data structures of all functions in the
3e293154 2038 callgraph to F. */
be95e2b9 2039
3e293154 2040void
ca30a539 2041ipa_print_all_params (FILE * f)
3e293154
MJ
2042{
2043 struct cgraph_node *node;
2044
ca30a539 2045 fprintf (f, "\nFunction parameters:\n");
3e293154 2046 for (node = cgraph_nodes; node; node = node->next)
ca30a539 2047 ipa_print_node_params (f, node);
3e293154 2048}
3f84bf08
MJ
2049
2050/* Return a heap allocated vector containing formal parameters of FNDECL. */
2051
2052VEC(tree, heap) *
2053ipa_get_vector_of_formal_parms (tree fndecl)
2054{
2055 VEC(tree, heap) *args;
2056 int count;
2057 tree parm;
2058
310bc633 2059 count = count_formal_params (fndecl);
3f84bf08 2060 args = VEC_alloc (tree, heap, count);
910ad8de 2061 for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
3f84bf08
MJ
2062 VEC_quick_push (tree, args, parm);
2063
2064 return args;
2065}
2066
2067/* Return a heap allocated vector containing types of formal parameters of
2068 function type FNTYPE. */
2069
2070static inline VEC(tree, heap) *
2071get_vector_of_formal_parm_types (tree fntype)
2072{
2073 VEC(tree, heap) *types;
2074 int count = 0;
2075 tree t;
2076
2077 for (t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t))
2078 count++;
2079
2080 types = VEC_alloc (tree, heap, count);
2081 for (t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t))
2082 VEC_quick_push (tree, types, TREE_VALUE (t));
2083
2084 return types;
2085}
2086
2087/* Modify the function declaration FNDECL and its type according to the plan in
2088 ADJUSTMENTS. It also sets base fields of individual adjustments structures
2089 to reflect the actual parameters being modified which are determined by the
2090 base_index field. */
2091
2092void
2093ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments,
2094 const char *synth_parm_prefix)
2095{
2096 VEC(tree, heap) *oparms, *otypes;
2097 tree orig_type, new_type = NULL;
2098 tree old_arg_types, t, new_arg_types = NULL;
2099 tree parm, *link = &DECL_ARGUMENTS (fndecl);
2100 int i, len = VEC_length (ipa_parm_adjustment_t, adjustments);
2101 tree new_reversed = NULL;
2102 bool care_for_types, last_parm_void;
2103
2104 if (!synth_parm_prefix)
2105 synth_parm_prefix = "SYNTH";
2106
2107 oparms = ipa_get_vector_of_formal_parms (fndecl);
2108 orig_type = TREE_TYPE (fndecl);
2109 old_arg_types = TYPE_ARG_TYPES (orig_type);
2110
2111 /* The following test is an ugly hack, some functions simply don't have any
2112 arguments in their type. This is probably a bug but well... */
2113 care_for_types = (old_arg_types != NULL_TREE);
2114 if (care_for_types)
2115 {
2116 last_parm_void = (TREE_VALUE (tree_last (old_arg_types))
2117 == void_type_node);
2118 otypes = get_vector_of_formal_parm_types (orig_type);
2119 if (last_parm_void)
2120 gcc_assert (VEC_length (tree, oparms) + 1 == VEC_length (tree, otypes));
2121 else
2122 gcc_assert (VEC_length (tree, oparms) == VEC_length (tree, otypes));
2123 }
2124 else
2125 {
2126 last_parm_void = false;
2127 otypes = NULL;
2128 }
2129
2130 for (i = 0; i < len; i++)
2131 {
2132 struct ipa_parm_adjustment *adj;
2133 gcc_assert (link);
2134
2135 adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
2136 parm = VEC_index (tree, oparms, adj->base_index);
2137 adj->base = parm;
2138
2139 if (adj->copy_param)
2140 {
2141 if (care_for_types)
2142 new_arg_types = tree_cons (NULL_TREE, VEC_index (tree, otypes,
2143 adj->base_index),
2144 new_arg_types);
2145 *link = parm;
910ad8de 2146 link = &DECL_CHAIN (parm);
3f84bf08
MJ
2147 }
2148 else if (!adj->remove_param)
2149 {
2150 tree new_parm;
2151 tree ptype;
2152
2153 if (adj->by_ref)
2154 ptype = build_pointer_type (adj->type);
2155 else
2156 ptype = adj->type;
2157
2158 if (care_for_types)
2159 new_arg_types = tree_cons (NULL_TREE, ptype, new_arg_types);
2160
2161 new_parm = build_decl (UNKNOWN_LOCATION, PARM_DECL, NULL_TREE,
2162 ptype);
2163 DECL_NAME (new_parm) = create_tmp_var_name (synth_parm_prefix);
2164
2165 DECL_ARTIFICIAL (new_parm) = 1;
2166 DECL_ARG_TYPE (new_parm) = ptype;
2167 DECL_CONTEXT (new_parm) = fndecl;
2168 TREE_USED (new_parm) = 1;
2169 DECL_IGNORED_P (new_parm) = 1;
2170 layout_decl (new_parm, 0);
2171
2172 add_referenced_var (new_parm);
2173 mark_sym_for_renaming (new_parm);
2174 adj->base = parm;
2175 adj->reduction = new_parm;
2176
2177 *link = new_parm;
2178
910ad8de 2179 link = &DECL_CHAIN (new_parm);
3f84bf08
MJ
2180 }
2181 }
2182
2183 *link = NULL_TREE;
2184
2185 if (care_for_types)
2186 {
2187 new_reversed = nreverse (new_arg_types);
2188 if (last_parm_void)
2189 {
2190 if (new_reversed)
2191 TREE_CHAIN (new_arg_types) = void_list_node;
2192 else
2193 new_reversed = void_list_node;
2194 }
2195 }
2196
2197 /* Use copy_node to preserve as much as possible from original type
2198 (debug info, attribute lists etc.)
2199 Exception is METHOD_TYPEs must have THIS argument.
2200 When we are asked to remove it, we need to build new FUNCTION_TYPE
2201 instead. */
2202 if (TREE_CODE (orig_type) != METHOD_TYPE
2203 || (VEC_index (ipa_parm_adjustment_t, adjustments, 0)->copy_param
2204 && VEC_index (ipa_parm_adjustment_t, adjustments, 0)->base_index == 0))
2205 {
4eb3f32c 2206 new_type = build_distinct_type_copy (orig_type);
3f84bf08
MJ
2207 TYPE_ARG_TYPES (new_type) = new_reversed;
2208 }
2209 else
2210 {
2211 new_type
2212 = build_distinct_type_copy (build_function_type (TREE_TYPE (orig_type),
2213 new_reversed));
2214 TYPE_CONTEXT (new_type) = TYPE_CONTEXT (orig_type);
2215 DECL_VINDEX (fndecl) = NULL_TREE;
2216 }
2217
d402c33d
JH
2218 /* When signature changes, we need to clear builtin info. */
2219 if (DECL_BUILT_IN (fndecl))
2220 {
2221 DECL_BUILT_IN_CLASS (fndecl) = NOT_BUILT_IN;
2222 DECL_FUNCTION_CODE (fndecl) = (enum built_in_function) 0;
2223 }
2224
3f84bf08
MJ
2225 /* This is a new type, not a copy of an old type. Need to reassociate
2226 variants. We can handle everything except the main variant lazily. */
2227 t = TYPE_MAIN_VARIANT (orig_type);
2228 if (orig_type != t)
2229 {
2230 TYPE_MAIN_VARIANT (new_type) = t;
2231 TYPE_NEXT_VARIANT (new_type) = TYPE_NEXT_VARIANT (t);
2232 TYPE_NEXT_VARIANT (t) = new_type;
2233 }
2234 else
2235 {
2236 TYPE_MAIN_VARIANT (new_type) = new_type;
2237 TYPE_NEXT_VARIANT (new_type) = NULL;
2238 }
2239
2240 TREE_TYPE (fndecl) = new_type;
9b389a5e 2241 DECL_VIRTUAL_P (fndecl) = 0;
3f84bf08
MJ
2242 if (otypes)
2243 VEC_free (tree, heap, otypes);
2244 VEC_free (tree, heap, oparms);
2245}
2246
2247/* Modify actual arguments of a function call CS as indicated in ADJUSTMENTS.
2248 If this is a directly recursive call, CS must be NULL. Otherwise it must
2249 contain the corresponding call graph edge. */
2250
2251void
2252ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
2253 ipa_parm_adjustment_vec adjustments)
2254{
2255 VEC(tree, heap) *vargs;
ddb555ed 2256 VEC(tree, gc) **debug_args = NULL;
3f84bf08
MJ
2257 gimple new_stmt;
2258 gimple_stmt_iterator gsi;
2259 tree callee_decl;
2260 int i, len;
2261
2262 len = VEC_length (ipa_parm_adjustment_t, adjustments);
2263 vargs = VEC_alloc (tree, heap, len);
ddb555ed 2264 callee_decl = !cs ? gimple_call_fndecl (stmt) : cs->callee->decl;
3f84bf08
MJ
2265
2266 gsi = gsi_for_stmt (stmt);
2267 for (i = 0; i < len; i++)
2268 {
2269 struct ipa_parm_adjustment *adj;
2270
2271 adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
2272
2273 if (adj->copy_param)
2274 {
2275 tree arg = gimple_call_arg (stmt, adj->base_index);
2276
2277 VEC_quick_push (tree, vargs, arg);
2278 }
2279 else if (!adj->remove_param)
2280 {
fffe1e40
MJ
2281 tree expr, base, off;
2282 location_t loc;
2283
2284 /* We create a new parameter out of the value of the old one, we can
2285 do the following kind of transformations:
2286
2287 - A scalar passed by reference is converted to a scalar passed by
2288 value. (adj->by_ref is false and the type of the original
2289 actual argument is a pointer to a scalar).
2290
2291 - A part of an aggregate is passed instead of the whole aggregate.
2292 The part can be passed either by value or by reference, this is
2293 determined by value of adj->by_ref. Moreover, the code below
2294 handles both situations when the original aggregate is passed by
2295 value (its type is not a pointer) and when it is passed by
2296 reference (it is a pointer to an aggregate).
2297
2298 When the new argument is passed by reference (adj->by_ref is true)
2299 it must be a part of an aggregate and therefore we form it by
2300 simply taking the address of a reference inside the original
2301 aggregate. */
2302
2303 gcc_checking_assert (adj->offset % BITS_PER_UNIT == 0);
2304 base = gimple_call_arg (stmt, adj->base_index);
2305 loc = EXPR_LOCATION (base);
2306
82d49829
MJ
2307 if (TREE_CODE (base) != ADDR_EXPR
2308 && POINTER_TYPE_P (TREE_TYPE (base)))
2309 off = build_int_cst (adj->alias_ptr_type,
fffe1e40 2310 adj->offset / BITS_PER_UNIT);
3f84bf08 2311 else
3f84bf08 2312 {
fffe1e40
MJ
2313 HOST_WIDE_INT base_offset;
2314 tree prev_base;
2315
2316 if (TREE_CODE (base) == ADDR_EXPR)
2317 base = TREE_OPERAND (base, 0);
2318 prev_base = base;
2319 base = get_addr_base_and_unit_offset (base, &base_offset);
2320 /* Aggregate arguments can have non-invariant addresses. */
2321 if (!base)
2322 {
2323 base = build_fold_addr_expr (prev_base);
82d49829 2324 off = build_int_cst (adj->alias_ptr_type,
fffe1e40
MJ
2325 adj->offset / BITS_PER_UNIT);
2326 }
2327 else if (TREE_CODE (base) == MEM_REF)
2328 {
82d49829 2329 off = build_int_cst (adj->alias_ptr_type,
fffe1e40
MJ
2330 base_offset
2331 + adj->offset / BITS_PER_UNIT);
2332 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1),
d35936ab 2333 off);
fffe1e40
MJ
2334 base = TREE_OPERAND (base, 0);
2335 }
2336 else
2337 {
82d49829 2338 off = build_int_cst (adj->alias_ptr_type,
fffe1e40
MJ
2339 base_offset
2340 + adj->offset / BITS_PER_UNIT);
2341 base = build_fold_addr_expr (base);
2342 }
3f84bf08 2343 }
fffe1e40
MJ
2344
2345 expr = fold_build2_loc (loc, MEM_REF, adj->type, base, off);
2346 if (adj->by_ref)
2347 expr = build_fold_addr_expr (expr);
2348
3f84bf08
MJ
2349 expr = force_gimple_operand_gsi (&gsi, expr,
2350 adj->by_ref
2351 || is_gimple_reg_type (adj->type),
2352 NULL, true, GSI_SAME_STMT);
2353 VEC_quick_push (tree, vargs, expr);
2354 }
ddb555ed
JJ
2355 if (!adj->copy_param && MAY_HAVE_DEBUG_STMTS)
2356 {
2357 unsigned int ix;
2358 tree ddecl = NULL_TREE, origin = DECL_ORIGIN (adj->base), arg;
2359 gimple def_temp;
2360
2361 arg = gimple_call_arg (stmt, adj->base_index);
2362 if (!useless_type_conversion_p (TREE_TYPE (origin), TREE_TYPE (arg)))
2363 {
2364 if (!fold_convertible_p (TREE_TYPE (origin), arg))
2365 continue;
2366 arg = fold_convert_loc (gimple_location (stmt),
2367 TREE_TYPE (origin), arg);
2368 }
2369 if (debug_args == NULL)
2370 debug_args = decl_debug_args_insert (callee_decl);
2371 for (ix = 0; VEC_iterate (tree, *debug_args, ix, ddecl); ix += 2)
2372 if (ddecl == origin)
2373 {
2374 ddecl = VEC_index (tree, *debug_args, ix + 1);
2375 break;
2376 }
2377 if (ddecl == NULL)
2378 {
2379 ddecl = make_node (DEBUG_EXPR_DECL);
2380 DECL_ARTIFICIAL (ddecl) = 1;
2381 TREE_TYPE (ddecl) = TREE_TYPE (origin);
2382 DECL_MODE (ddecl) = DECL_MODE (origin);
2383
2384 VEC_safe_push (tree, gc, *debug_args, origin);
2385 VEC_safe_push (tree, gc, *debug_args, ddecl);
2386 }
2387 def_temp = gimple_build_debug_bind (ddecl, unshare_expr (arg),
2388 stmt);
2389 gsi_insert_before (&gsi, def_temp, GSI_SAME_STMT);
2390 }
3f84bf08
MJ
2391 }
2392
2393 if (dump_file && (dump_flags & TDF_DETAILS))
2394 {
2395 fprintf (dump_file, "replacing stmt:");
2396 print_gimple_stmt (dump_file, gsi_stmt (gsi), 0, 0);
2397 }
2398
3f84bf08
MJ
2399 new_stmt = gimple_build_call_vec (callee_decl, vargs);
2400 VEC_free (tree, heap, vargs);
2401 if (gimple_call_lhs (stmt))
2402 gimple_call_set_lhs (new_stmt, gimple_call_lhs (stmt));
2403
2404 gimple_set_block (new_stmt, gimple_block (stmt));
2405 if (gimple_has_location (stmt))
2406 gimple_set_location (new_stmt, gimple_location (stmt));
2407 gimple_call_copy_flags (new_stmt, stmt);
2408 gimple_call_set_chain (new_stmt, gimple_call_chain (stmt));
2409
2410 if (dump_file && (dump_flags & TDF_DETAILS))
2411 {
2412 fprintf (dump_file, "with stmt:");
2413 print_gimple_stmt (dump_file, new_stmt, 0, 0);
2414 fprintf (dump_file, "\n");
2415 }
2416 gsi_replace (&gsi, new_stmt, true);
2417 if (cs)
2418 cgraph_set_call_stmt (cs, new_stmt);
2419 update_ssa (TODO_update_ssa);
2420 free_dominance_info (CDI_DOMINATORS);
2421}
2422
2423/* Return true iff BASE_INDEX is in ADJUSTMENTS more than once. */
2424
2425static bool
2426index_in_adjustments_multiple_times_p (int base_index,
2427 ipa_parm_adjustment_vec adjustments)
2428{
2429 int i, len = VEC_length (ipa_parm_adjustment_t, adjustments);
2430 bool one = false;
2431
2432 for (i = 0; i < len; i++)
2433 {
2434 struct ipa_parm_adjustment *adj;
2435 adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
2436
2437 if (adj->base_index == base_index)
2438 {
2439 if (one)
2440 return true;
2441 else
2442 one = true;
2443 }
2444 }
2445 return false;
2446}
2447
2448
2449/* Return adjustments that should have the same effect on function parameters
2450 and call arguments as if they were first changed according to adjustments in
2451 INNER and then by adjustments in OUTER. */
2452
2453ipa_parm_adjustment_vec
2454ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
2455 ipa_parm_adjustment_vec outer)
2456{
2457 int i, outlen = VEC_length (ipa_parm_adjustment_t, outer);
2458 int inlen = VEC_length (ipa_parm_adjustment_t, inner);
2459 int removals = 0;
2460 ipa_parm_adjustment_vec adjustments, tmp;
2461
2462 tmp = VEC_alloc (ipa_parm_adjustment_t, heap, inlen);
2463 for (i = 0; i < inlen; i++)
2464 {
2465 struct ipa_parm_adjustment *n;
2466 n = VEC_index (ipa_parm_adjustment_t, inner, i);
2467
2468 if (n->remove_param)
2469 removals++;
2470 else
2471 VEC_quick_push (ipa_parm_adjustment_t, tmp, n);
2472 }
2473
2474 adjustments = VEC_alloc (ipa_parm_adjustment_t, heap, outlen + removals);
2475 for (i = 0; i < outlen; i++)
2476 {
2477 struct ipa_parm_adjustment *r;
2478 struct ipa_parm_adjustment *out = VEC_index (ipa_parm_adjustment_t,
2479 outer, i);
2480 struct ipa_parm_adjustment *in = VEC_index (ipa_parm_adjustment_t, tmp,
2481 out->base_index);
2482
2483 gcc_assert (!in->remove_param);
2484 if (out->remove_param)
2485 {
2486 if (!index_in_adjustments_multiple_times_p (in->base_index, tmp))
2487 {
2488 r = VEC_quick_push (ipa_parm_adjustment_t, adjustments, NULL);
2489 memset (r, 0, sizeof (*r));
2490 r->remove_param = true;
2491 }
2492 continue;
2493 }
2494
2495 r = VEC_quick_push (ipa_parm_adjustment_t, adjustments, NULL);
2496 memset (r, 0, sizeof (*r));
2497 r->base_index = in->base_index;
2498 r->type = out->type;
2499
2500 /* FIXME: Create nonlocal value too. */
2501
2502 if (in->copy_param && out->copy_param)
2503 r->copy_param = true;
2504 else if (in->copy_param)
2505 r->offset = out->offset;
2506 else if (out->copy_param)
2507 r->offset = in->offset;
2508 else
2509 r->offset = in->offset + out->offset;
2510 }
2511
2512 for (i = 0; i < inlen; i++)
2513 {
2514 struct ipa_parm_adjustment *n = VEC_index (ipa_parm_adjustment_t,
2515 inner, i);
2516
2517 if (n->remove_param)
2518 VEC_quick_push (ipa_parm_adjustment_t, adjustments, n);
2519 }
2520
2521 VEC_free (ipa_parm_adjustment_t, heap, tmp);
2522 return adjustments;
2523}
2524
2525/* Dump the adjustments in the vector ADJUSTMENTS to dump_file in a human
2526 friendly way, assuming they are meant to be applied to FNDECL. */
2527
2528void
2529ipa_dump_param_adjustments (FILE *file, ipa_parm_adjustment_vec adjustments,
2530 tree fndecl)
2531{
2532 int i, len = VEC_length (ipa_parm_adjustment_t, adjustments);
2533 bool first = true;
2534 VEC(tree, heap) *parms = ipa_get_vector_of_formal_parms (fndecl);
2535
2536 fprintf (file, "IPA param adjustments: ");
2537 for (i = 0; i < len; i++)
2538 {
2539 struct ipa_parm_adjustment *adj;
2540 adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
2541
2542 if (!first)
2543 fprintf (file, " ");
2544 else
2545 first = false;
2546
2547 fprintf (file, "%i. base_index: %i - ", i, adj->base_index);
2548 print_generic_expr (file, VEC_index (tree, parms, adj->base_index), 0);
2549 if (adj->base)
2550 {
2551 fprintf (file, ", base: ");
2552 print_generic_expr (file, adj->base, 0);
2553 }
2554 if (adj->reduction)
2555 {
2556 fprintf (file, ", reduction: ");
2557 print_generic_expr (file, adj->reduction, 0);
2558 }
2559 if (adj->new_ssa_base)
2560 {
2561 fprintf (file, ", new_ssa_base: ");
2562 print_generic_expr (file, adj->new_ssa_base, 0);
2563 }
2564
2565 if (adj->copy_param)
2566 fprintf (file, ", copy_param");
2567 else if (adj->remove_param)
2568 fprintf (file, ", remove_param");
2569 else
2570 fprintf (file, ", offset %li", (long) adj->offset);
2571 if (adj->by_ref)
2572 fprintf (file, ", by_ref");
2573 print_node_brief (file, ", type: ", adj->type, 0);
2574 fprintf (file, "\n");
2575 }
2576 VEC_free (tree, heap, parms);
2577}
2578
fb3f88cc
JH
2579/* Stream out jump function JUMP_FUNC to OB. */
2580
2581static void
2582ipa_write_jump_function (struct output_block *ob,
2583 struct ipa_jump_func *jump_func)
2584{
412288f1 2585 streamer_write_uhwi (ob, jump_func->type);
fb3f88cc
JH
2586
2587 switch (jump_func->type)
2588 {
2589 case IPA_JF_UNKNOWN:
2590 break;
b258210c 2591 case IPA_JF_KNOWN_TYPE:
b9393656 2592 stream_write_tree (ob, jump_func->value.base_binfo, true);
b258210c 2593 break;
fb3f88cc 2594 case IPA_JF_CONST:
b9393656 2595 stream_write_tree (ob, jump_func->value.constant, true);
fb3f88cc
JH
2596 break;
2597 case IPA_JF_PASS_THROUGH:
b9393656 2598 stream_write_tree (ob, jump_func->value.pass_through.operand, true);
412288f1
DN
2599 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
2600 streamer_write_uhwi (ob, jump_func->value.pass_through.operation);
fb3f88cc
JH
2601 break;
2602 case IPA_JF_ANCESTOR:
412288f1 2603 streamer_write_uhwi (ob, jump_func->value.ancestor.offset);
b9393656 2604 stream_write_tree (ob, jump_func->value.ancestor.type, true);
412288f1 2605 streamer_write_uhwi (ob, jump_func->value.ancestor.formal_id);
fb3f88cc
JH
2606 break;
2607 case IPA_JF_CONST_MEMBER_PTR:
b9393656
DN
2608 stream_write_tree (ob, jump_func->value.member_cst.pfn, true);
2609 stream_write_tree (ob, jump_func->value.member_cst.delta, false);
fb3f88cc
JH
2610 break;
2611 }
2612}
2613
2614/* Read in jump function JUMP_FUNC from IB. */
2615
2616static void
2617ipa_read_jump_function (struct lto_input_block *ib,
2618 struct ipa_jump_func *jump_func,
2619 struct data_in *data_in)
2620{
412288f1 2621 jump_func->type = (enum jump_func_type) streamer_read_uhwi (ib);
fb3f88cc
JH
2622
2623 switch (jump_func->type)
2624 {
2625 case IPA_JF_UNKNOWN:
2626 break;
b258210c 2627 case IPA_JF_KNOWN_TYPE:
b9393656 2628 jump_func->value.base_binfo = stream_read_tree (ib, data_in);
b258210c 2629 break;
fb3f88cc 2630 case IPA_JF_CONST:
b9393656 2631 jump_func->value.constant = stream_read_tree (ib, data_in);
fb3f88cc
JH
2632 break;
2633 case IPA_JF_PASS_THROUGH:
b9393656 2634 jump_func->value.pass_through.operand = stream_read_tree (ib, data_in);
412288f1
DN
2635 jump_func->value.pass_through.formal_id = streamer_read_uhwi (ib);
2636 jump_func->value.pass_through.operation
2637 = (enum tree_code) streamer_read_uhwi (ib);
fb3f88cc
JH
2638 break;
2639 case IPA_JF_ANCESTOR:
412288f1 2640 jump_func->value.ancestor.offset = streamer_read_uhwi (ib);
b9393656 2641 jump_func->value.ancestor.type = stream_read_tree (ib, data_in);
412288f1 2642 jump_func->value.ancestor.formal_id = streamer_read_uhwi (ib);
fb3f88cc
JH
2643 break;
2644 case IPA_JF_CONST_MEMBER_PTR:
b9393656
DN
2645 jump_func->value.member_cst.pfn = stream_read_tree (ib, data_in);
2646 jump_func->value.member_cst.delta = stream_read_tree (ib, data_in);
fb3f88cc
JH
2647 break;
2648 }
2649}
2650
e33c6cd6
MJ
2651/* Stream out parts of cgraph_indirect_call_info corresponding to CS that are
2652 relevant to indirect inlining to OB. */
661e7330
MJ
2653
2654static void
e33c6cd6
MJ
2655ipa_write_indirect_edge_info (struct output_block *ob,
2656 struct cgraph_edge *cs)
661e7330 2657{
e33c6cd6 2658 struct cgraph_indirect_call_info *ii = cs->indirect_info;
2465dcc2 2659 struct bitpack_d bp;
e33c6cd6 2660
412288f1
DN
2661 streamer_write_hwi (ob, ii->param_index);
2662 streamer_write_hwi (ob, ii->anc_offset);
2465dcc2
RG
2663 bp = bitpack_create (ob->main_stream);
2664 bp_pack_value (&bp, ii->polymorphic, 1);
412288f1 2665 streamer_write_bitpack (&bp);
b258210c
MJ
2666
2667 if (ii->polymorphic)
2668 {
412288f1 2669 streamer_write_hwi (ob, ii->otr_token);
b9393656 2670 stream_write_tree (ob, ii->otr_type, true);
b258210c 2671 }
661e7330
MJ
2672}
2673
e33c6cd6
MJ
2674/* Read in parts of cgraph_indirect_call_info corresponding to CS that are
2675 relevant to indirect inlining from IB. */
661e7330
MJ
2676
2677static void
e33c6cd6
MJ
2678ipa_read_indirect_edge_info (struct lto_input_block *ib,
2679 struct data_in *data_in ATTRIBUTE_UNUSED,
2680 struct cgraph_edge *cs)
661e7330 2681{
e33c6cd6 2682 struct cgraph_indirect_call_info *ii = cs->indirect_info;
2465dcc2 2683 struct bitpack_d bp;
661e7330 2684
412288f1
DN
2685 ii->param_index = (int) streamer_read_hwi (ib);
2686 ii->anc_offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
2687 bp = streamer_read_bitpack (ib);
2465dcc2 2688 ii->polymorphic = bp_unpack_value (&bp, 1);
b258210c
MJ
2689 if (ii->polymorphic)
2690 {
412288f1 2691 ii->otr_token = (HOST_WIDE_INT) streamer_read_hwi (ib);
b9393656 2692 ii->otr_type = stream_read_tree (ib, data_in);
b258210c 2693 }
661e7330
MJ
2694}
2695
fb3f88cc
JH
2696/* Stream out NODE info to OB. */
2697
2698static void
2699ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
2700{
2701 int node_ref;
2702 lto_cgraph_encoder_t encoder;
2703 struct ipa_node_params *info = IPA_NODE_REF (node);
2704 int j;
2705 struct cgraph_edge *e;
2465dcc2 2706 struct bitpack_d bp;
fb3f88cc
JH
2707
2708 encoder = ob->decl_state->cgraph_node_encoder;
2709 node_ref = lto_cgraph_encoder_encode (encoder, node);
412288f1 2710 streamer_write_uhwi (ob, node_ref);
fb3f88cc 2711
2465dcc2 2712 bp = bitpack_create (ob->main_stream);
062c604f 2713 gcc_assert (info->uses_analysis_done
661e7330 2714 || ipa_get_param_count (info) == 0);
fb3f88cc
JH
2715 gcc_assert (!info->node_enqueued);
2716 gcc_assert (!info->ipcp_orig_node);
2717 for (j = 0; j < ipa_get_param_count (info); j++)
310bc633 2718 bp_pack_value (&bp, ipa_is_param_used (info, j), 1);
412288f1 2719 streamer_write_bitpack (&bp);
fb3f88cc
JH
2720 for (e = node->callees; e; e = e->next_callee)
2721 {
2722 struct ipa_edge_args *args = IPA_EDGE_REF (e);
2723
412288f1 2724 streamer_write_uhwi (ob, ipa_get_cs_argument_count (args));
fb3f88cc
JH
2725 for (j = 0; j < ipa_get_cs_argument_count (args); j++)
2726 ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
2727 }
e33c6cd6 2728 for (e = node->indirect_calls; e; e = e->next_callee)
c8246dbe
JH
2729 {
2730 struct ipa_edge_args *args = IPA_EDGE_REF (e);
2731
412288f1 2732 streamer_write_uhwi (ob, ipa_get_cs_argument_count (args));
c8246dbe
JH
2733 for (j = 0; j < ipa_get_cs_argument_count (args); j++)
2734 ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
2735 ipa_write_indirect_edge_info (ob, e);
2736 }
fb3f88cc
JH
2737}
2738
61502ca8 2739/* Stream in NODE info from IB. */
fb3f88cc
JH
2740
2741static void
2742ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
2743 struct data_in *data_in)
2744{
2745 struct ipa_node_params *info = IPA_NODE_REF (node);
2746 int k;
2747 struct cgraph_edge *e;
2465dcc2 2748 struct bitpack_d bp;
fb3f88cc
JH
2749
2750 ipa_initialize_node_params (node);
2751
412288f1 2752 bp = streamer_read_bitpack (ib);
fb3f88cc 2753 if (ipa_get_param_count (info) != 0)
062c604f 2754 info->uses_analysis_done = true;
fb3f88cc
JH
2755 info->node_enqueued = false;
2756 for (k = 0; k < ipa_get_param_count (info); k++)
310bc633 2757 ipa_set_param_used (info, k, bp_unpack_value (&bp, 1));
fb3f88cc
JH
2758 for (e = node->callees; e; e = e->next_callee)
2759 {
2760 struct ipa_edge_args *args = IPA_EDGE_REF (e);
412288f1 2761 int count = streamer_read_uhwi (ib);
fb3f88cc 2762
fb3f88cc
JH
2763 if (!count)
2764 continue;
606d9a09 2765 VEC_safe_grow_cleared (ipa_jump_func_t, gc, args->jump_functions, count);
fb3f88cc 2766
fb3f88cc
JH
2767 for (k = 0; k < ipa_get_cs_argument_count (args); k++)
2768 ipa_read_jump_function (ib, ipa_get_ith_jump_func (args, k), data_in);
2769 }
e33c6cd6 2770 for (e = node->indirect_calls; e; e = e->next_callee)
c8246dbe
JH
2771 {
2772 struct ipa_edge_args *args = IPA_EDGE_REF (e);
412288f1 2773 int count = streamer_read_uhwi (ib);
c8246dbe 2774
c8246dbe
JH
2775 if (count)
2776 {
606d9a09
MJ
2777 VEC_safe_grow_cleared (ipa_jump_func_t, gc, args->jump_functions,
2778 count);
c8246dbe 2779 for (k = 0; k < ipa_get_cs_argument_count (args); k++)
606d9a09
MJ
2780 ipa_read_jump_function (ib, ipa_get_ith_jump_func (args, k),
2781 data_in);
c8246dbe
JH
2782 }
2783 ipa_read_indirect_edge_info (ib, data_in, e);
2784 }
fb3f88cc
JH
2785}
2786
2787/* Write jump functions for nodes in SET. */
2788
2789void
2790ipa_prop_write_jump_functions (cgraph_node_set set)
2791{
2792 struct cgraph_node *node;
93536c97 2793 struct output_block *ob;
fb3f88cc
JH
2794 unsigned int count = 0;
2795 cgraph_node_set_iterator csi;
2796
93536c97
MJ
2797 if (!ipa_node_params_vector)
2798 return;
fb3f88cc 2799
93536c97
MJ
2800 ob = create_output_block (LTO_section_jump_functions);
2801 ob->cgraph_node = NULL;
fb3f88cc
JH
2802 for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
2803 {
2804 node = csi_node (csi);
c47d0034
JH
2805 if (cgraph_function_with_gimple_body_p (node)
2806 && IPA_NODE_REF (node) != NULL)
fb3f88cc
JH
2807 count++;
2808 }
2809
412288f1 2810 streamer_write_uhwi (ob, count);
fb3f88cc
JH
2811
2812 /* Process all of the functions. */
2813 for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
2814 {
2815 node = csi_node (csi);
c47d0034
JH
2816 if (cgraph_function_with_gimple_body_p (node)
2817 && IPA_NODE_REF (node) != NULL)
fb3f88cc
JH
2818 ipa_write_node_info (ob, node);
2819 }
412288f1 2820 streamer_write_char_stream (ob->main_stream, 0);
fb3f88cc
JH
2821 produce_asm (ob, NULL);
2822 destroy_output_block (ob);
2823}
2824
2825/* Read section in file FILE_DATA of length LEN with data DATA. */
2826
2827static void
2828ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
2829 size_t len)
2830{
2831 const struct lto_function_header *header =
2832 (const struct lto_function_header *) data;
2833 const int32_t cfg_offset = sizeof (struct lto_function_header);
2834 const int32_t main_offset = cfg_offset + header->cfg_size;
2835 const int32_t string_offset = main_offset + header->main_size;
2836 struct data_in *data_in;
2837 struct lto_input_block ib_main;
2838 unsigned int i;
2839 unsigned int count;
2840
2841 LTO_INIT_INPUT_BLOCK (ib_main, (const char *) data + main_offset, 0,
2842 header->main_size);
2843
2844 data_in =
2845 lto_data_in_create (file_data, (const char *) data + string_offset,
2846 header->string_size, NULL);
412288f1 2847 count = streamer_read_uhwi (&ib_main);
fb3f88cc
JH
2848
2849 for (i = 0; i < count; i++)
2850 {
2851 unsigned int index;
2852 struct cgraph_node *node;
2853 lto_cgraph_encoder_t encoder;
2854
412288f1 2855 index = streamer_read_uhwi (&ib_main);
fb3f88cc
JH
2856 encoder = file_data->cgraph_node_encoder;
2857 node = lto_cgraph_encoder_deref (encoder, index);
9b3cf76a 2858 gcc_assert (node->analyzed);
fb3f88cc
JH
2859 ipa_read_node_info (&ib_main, node, data_in);
2860 }
2861 lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
2862 len);
2863 lto_data_in_delete (data_in);
2864}
2865
2866/* Read ipcp jump functions. */
2867
2868void
2869ipa_prop_read_jump_functions (void)
2870{
2871 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
2872 struct lto_file_decl_data *file_data;
2873 unsigned int j = 0;
2874
2875 ipa_check_create_node_params ();
2876 ipa_check_create_edge_args ();
2877 ipa_register_cgraph_hooks ();
2878
2879 while ((file_data = file_data_vec[j++]))
2880 {
2881 size_t len;
2882 const char *data = lto_get_section_data (file_data, LTO_section_jump_functions, NULL, &len);
2883
2884 if (data)
2885 ipa_prop_read_section (file_data, data, len);
2886 }
2887}
2888
b8698a0f 2889/* After merging units, we can get mismatch in argument counts.
61502ca8 2890 Also decl merging might've rendered parameter lists obsolete.
fb3f88cc
JH
2891 Also compute called_with_variable_arg info. */
2892
2893void
2894ipa_update_after_lto_read (void)
2895{
2896 struct cgraph_node *node;
fb3f88cc 2897
05d3aa37
MJ
2898 ipa_check_create_node_params ();
2899 ipa_check_create_edge_args ();
2900
fb3f88cc 2901 for (node = cgraph_nodes; node; node = node->next)
563cb662 2902 if (node->analyzed)
05d3aa37 2903 ipa_initialize_node_params (node);
fb3f88cc 2904}
This page took 2.639096 seconds and 5 git commands to generate.