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