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