]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ipa-prop.c
configure.ac (cygwin noconfigdirs): Remove libgcj.
[thirdparty/gcc.git] / gcc / ipa-prop.c
CommitLineData
518dc859 1/* Interprocedural analyses.
32e8bb8e 2 Copyright (C) 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
518dc859
RL
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
9dcd6f09 8Software Foundation; either version 3, or (at your option) any later
518dc859
RL
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
9dcd6f09
NC
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
518dc859
RL
19
20#include "config.h"
21#include "system.h"
22#include "coretypes.h"
23#include "tree.h"
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"
771578a0 31#include "tree-inline.h"
518dc859
RL
32#include "flags.h"
33#include "timevar.h"
771578a0 34#include "flags.h"
3e293154 35#include "diagnostic.h"
771578a0
MJ
36
37/* Vector where the parameter infos are actually stored. */
38VEC (ipa_node_params_t, heap) *ipa_node_params_vector;
39/* Vector where the parameter infos are actually stored. */
40VEC (ipa_edge_args_t, heap) *ipa_edge_args_vector;
41
42/* Holders of ipa cgraph hooks: */
e2c9111c
JH
43static struct cgraph_edge_hook_list *edge_removal_hook_holder;
44static struct cgraph_node_hook_list *node_removal_hook_holder;
45static struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
46static struct cgraph_2node_hook_list *node_duplication_hook_holder;
518dc859 47
dcd416e3 48/* Initialize worklist to contain all functions. */
be95e2b9 49
dcd416e3
MJ
50struct ipa_func_list *
51ipa_init_func_list (void)
518dc859
RL
52{
53 struct cgraph_node *node;
dcd416e3 54 struct ipa_func_list * wl;
518dc859
RL
55
56 wl = NULL;
57 for (node = cgraph_nodes; node; node = node->next)
0eae6bab
MJ
58 if (node->analyzed)
59 {
60 /* Unreachable nodes should have been eliminated before ipcp and
61 inlining. */
62 gcc_assert (node->needed || node->reachable);
63 ipa_push_func_to_list (&wl, node);
64 }
518dc859
RL
65
66 return wl;
67}
68
dcd416e3 69/* Add cgraph node MT to the worklist. Set worklist element WL
518dc859 70 to point to MT. */
be95e2b9 71
518dc859 72void
dcd416e3 73ipa_push_func_to_list (struct ipa_func_list **wl, struct cgraph_node *mt)
518dc859 74{
dcd416e3 75 struct ipa_func_list *temp;
518dc859 76
d3bfe4de 77 temp = XCNEW (struct ipa_func_list);
dcd416e3
MJ
78 temp->node = mt;
79 temp->next = *wl;
518dc859
RL
80 *wl = temp;
81}
82
dcd416e3 83/* Remove a function from the worklist. WL points to the first
518dc859 84 element in the list, which is removed. */
be95e2b9 85
518dc859 86struct cgraph_node *
dcd416e3 87ipa_pop_func_from_list (struct ipa_func_list ** wl)
518dc859 88{
dcd416e3
MJ
89 struct ipa_func_list *first;
90 struct cgraph_node *return_func;
518dc859
RL
91
92 first = *wl;
dcd416e3
MJ
93 *wl = (*wl)->next;
94 return_func = first->node;
518dc859 95 free (first);
dcd416e3 96 return return_func;
518dc859
RL
97}
98
be95e2b9
MJ
99/* Return index of the formal whose tree is PTREE in function which corresponds
100 to INFO. */
101
518dc859 102static int
dcd416e3 103ipa_get_param_decl_index (struct ipa_node_params *info, tree ptree)
518dc859
RL
104{
105 int i, count;
106
dcd416e3 107 count = ipa_get_param_count (info);
518dc859 108 for (i = 0; i < count; i++)
f8e2a1ed 109 if (ipa_get_param(info, i) == ptree)
518dc859
RL
110 return i;
111
112 return -1;
113}
114
f8e2a1ed
MJ
115/* Populate the param_decl field in parameter descriptors of INFO that
116 corresponds to NODE. */
be95e2b9 117
f8e2a1ed
MJ
118static void
119ipa_populate_param_decls (struct cgraph_node *node,
120 struct ipa_node_params *info)
518dc859
RL
121{
122 tree fndecl;
123 tree fnargs;
124 tree parm;
125 int param_num;
3e293154 126
f8e2a1ed 127 fndecl = node->decl;
518dc859
RL
128 fnargs = DECL_ARGUMENTS (fndecl);
129 param_num = 0;
130 for (parm = fnargs; parm; parm = TREE_CHAIN (parm))
131 {
f8e2a1ed 132 info->params[param_num].decl = parm;
518dc859
RL
133 param_num++;
134 }
135}
136
f8e2a1ed
MJ
137/* Count number of formal parameters in NOTE. Store the result to the
138 appropriate field of INFO. */
be95e2b9 139
f8e2a1ed
MJ
140static void
141ipa_count_formal_params (struct cgraph_node *node,
142 struct ipa_node_params *info)
518dc859
RL
143{
144 tree fndecl;
145 tree fnargs;
146 tree parm;
147 int param_num;
148
f8e2a1ed 149 fndecl = node->decl;
518dc859
RL
150 fnargs = DECL_ARGUMENTS (fndecl);
151 param_num = 0;
152 for (parm = fnargs; parm; parm = TREE_CHAIN (parm))
153 param_num++;
f8e2a1ed
MJ
154 ipa_set_param_count (info, param_num);
155}
156
157/* Initialize the ipa_node_params structure associated with NODE by counting
158 the function parameters, creating the descriptors and populating their
159 param_decls. */
be95e2b9 160
f8e2a1ed
MJ
161void
162ipa_initialize_node_params (struct cgraph_node *node)
163{
164 struct ipa_node_params *info = IPA_NODE_REF (node);
165
166 if (!info->params)
167 {
168 ipa_count_formal_params (node, info);
169 info->params = XCNEWVEC (struct ipa_param_descriptor,
170 ipa_get_param_count (info));
171 ipa_populate_param_decls (node, info);
172 }
518dc859
RL
173}
174
8b75fc9b
MJ
175/* Callback of walk_stmt_load_store_addr_ops for the visit_store and visit_addr
176 parameters. If OP is a parameter declaration, mark it as modified in the
177 info structure passed in DATA. */
be95e2b9 178
8b75fc9b
MJ
179static bool
180visit_store_addr_for_mod_analysis (gimple stmt ATTRIBUTE_UNUSED,
181 tree op, void *data)
518dc859 182{
8b75fc9b 183 struct ipa_node_params *info = (struct ipa_node_params *) data;
518dc859 184
8b75fc9b 185 if (TREE_CODE (op) == PARM_DECL)
518dc859 186 {
8b75fc9b
MJ
187 int index = ipa_get_param_decl_index (info, op);
188 gcc_assert (index >= 0);
189 info->params[index].modified = true;
518dc859 190 }
8b75fc9b
MJ
191
192 return false;
518dc859
RL
193}
194
3e293154 195/* Compute which formal parameters of function associated with NODE are locally
8b75fc9b
MJ
196 modified or their address is taken. Note that this does not apply on
197 parameters with SSA names but those can and should be analyzed
198 differently. */
be95e2b9 199
518dc859 200void
3e293154 201ipa_detect_param_modifications (struct cgraph_node *node)
518dc859 202{
3e293154 203 tree decl = node->decl;
518dc859
RL
204 basic_block bb;
205 struct function *func;
726a989a 206 gimple_stmt_iterator gsi;
3e293154 207 struct ipa_node_params *info = IPA_NODE_REF (node);
518dc859 208
3e293154 209 if (ipa_get_param_count (info) == 0 || info->modification_analysis_done)
3cc1cccc
RL
210 return;
211
3e293154
MJ
212 func = DECL_STRUCT_FUNCTION (decl);
213 FOR_EACH_BB_FN (bb, func)
8b75fc9b
MJ
214 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
215 walk_stmt_load_store_addr_ops (gsi_stmt (gsi), info, NULL,
216 visit_store_addr_for_mod_analysis,
217 visit_store_addr_for_mod_analysis);
3e293154
MJ
218
219 info->modification_analysis_done = 1;
518dc859
RL
220}
221
be95e2b9 222/* Count number of arguments callsite CS has and store it in
dcd416e3 223 ipa_edge_args structure corresponding to this callsite. */
be95e2b9 224
518dc859 225void
dcd416e3 226ipa_count_arguments (struct cgraph_edge *cs)
518dc859 227{
726a989a 228 gimple stmt;
518dc859
RL
229 int arg_num;
230
726a989a
RB
231 stmt = cs->call_stmt;
232 gcc_assert (is_gimple_call (stmt));
233 arg_num = gimple_call_num_args (stmt);
129a37fc
JH
234 if (VEC_length (ipa_edge_args_t, ipa_edge_args_vector)
235 <= (unsigned) cgraph_edge_max_uid)
236 VEC_safe_grow_cleared (ipa_edge_args_t, heap,
237 ipa_edge_args_vector, cgraph_edge_max_uid + 1);
dcd416e3 238 ipa_set_cs_argument_count (IPA_EDGE_REF (cs), arg_num);
518dc859
RL
239}
240
be95e2b9
MJ
241/* Print the jump functions of all arguments on all call graph edges going from
242 NODE to file F. */
243
518dc859 244void
3e293154 245ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
518dc859 246{
3e293154
MJ
247 int i, count;
248 struct cgraph_edge *cs;
249 struct ipa_jump_func *jump_func;
250 enum jump_func_type type;
518dc859 251
ca30a539 252 fprintf (f, " Jump functions of caller %s:\n", cgraph_node_name (node));
3e293154
MJ
253 for (cs = node->callees; cs; cs = cs->next_callee)
254 {
255 if (!ipa_edge_args_info_available_for_edge_p (cs))
256 continue;
257
ca30a539 258 fprintf (f, " callsite %s ", cgraph_node_name (node));
3e293154 259 fprintf (f, "-> %s :: \n", cgraph_node_name (cs->callee));
518dc859 260
3e293154
MJ
261 count = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
262 for (i = 0; i < count; i++)
263 {
264 jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
265 type = jump_func->type;
266
ca30a539 267 fprintf (f, " param %d: ", i);
133f9369 268 if (type == IPA_JF_UNKNOWN)
3e293154 269 fprintf (f, "UNKNOWN\n");
133f9369 270 else if (type == IPA_JF_CONST)
3e293154
MJ
271 {
272 tree val = jump_func->value.constant;
273 fprintf (f, "CONST: ");
274 print_generic_expr (f, val, 0);
275 fprintf (f, "\n");
276 }
133f9369 277 else if (type == IPA_JF_CONST_MEMBER_PTR)
3e293154
MJ
278 {
279 fprintf (f, "CONST MEMBER PTR: ");
280 print_generic_expr (f, jump_func->value.member_cst.pfn, 0);
281 fprintf (f, ", ");
282 print_generic_expr (f, jump_func->value.member_cst.delta, 0);
283 fprintf (f, "\n");
284 }
133f9369 285 else if (type == IPA_JF_PASS_THROUGH)
3e293154
MJ
286 {
287 fprintf (f, "PASS THROUGH: ");
288 fprintf (f, "%d\n", jump_func->value.formal_id);
289 }
290 }
291 }
292}
293
294/* Print ipa_jump_func data structures of all nodes in the call graph to F. */
be95e2b9 295
3e293154
MJ
296void
297ipa_print_all_jump_functions (FILE *f)
298{
299 struct cgraph_node *node;
300
ca30a539 301 fprintf (f, "\nJump functions:\n");
3e293154
MJ
302 for (node = cgraph_nodes; node; node = node->next)
303 {
304 ipa_print_node_jump_functions (f, node);
305 }
306}
307
be95e2b9
MJ
308/* Determine the jump functions of scalar arguments. Scalar means SSA names
309 and constants of a number of selected types. INFO is the ipa_node_params
310 structure associated with the caller, FUNCTIONS is a pointer to an array of
311 jump function structures associated with CALL which is the call statement
312 being examined.*/
313
3e293154
MJ
314static void
315compute_scalar_jump_functions (struct ipa_node_params *info,
316 struct ipa_jump_func *functions,
726a989a 317 gimple call)
3e293154 318{
3e293154 319 tree arg;
726a989a 320 unsigned num = 0;
3e293154 321
726a989a 322 for (num = 0; num < gimple_call_num_args (call); num++)
518dc859 323 {
726a989a
RB
324 arg = gimple_call_arg (call, num);
325
00fc2333 326 if (is_gimple_ip_invariant (arg))
518dc859 327 {
133f9369 328 functions[num].type = IPA_JF_CONST;
3e293154
MJ
329 functions[num].value.constant = arg;
330 }
3e293154
MJ
331 else if ((TREE_CODE (arg) == SSA_NAME) && SSA_NAME_IS_DEFAULT_DEF (arg))
332 {
333 int index = ipa_get_param_decl_index (info, SSA_NAME_VAR (arg));
334
335 if (index >= 0)
518dc859 336 {
133f9369 337 functions[num].type = IPA_JF_PASS_THROUGH;
3e293154 338 functions[num].value.formal_id = index;
518dc859
RL
339 }
340 }
3e293154
MJ
341 }
342}
343
be95e2b9
MJ
344/* Inspect the given TYPE and return true iff it has the same structure (the
345 same number of fields of the same types) as a C++ member pointer. If
346 METHOD_PTR and DELTA are non-NULL, store the trees representing the
347 corresponding fields there. */
348
3e293154
MJ
349static bool
350type_like_member_ptr_p (tree type, tree *method_ptr, tree *delta)
351{
352 tree fld;
353
354 if (TREE_CODE (type) != RECORD_TYPE)
355 return false;
356
357 fld = TYPE_FIELDS (type);
358 if (!fld || !POINTER_TYPE_P (TREE_TYPE (fld))
359 || TREE_CODE (TREE_TYPE (TREE_TYPE (fld))) != METHOD_TYPE)
360 return false;
361
362 if (method_ptr)
363 *method_ptr = fld;
364
365 fld = TREE_CHAIN (fld);
366 if (!fld || INTEGRAL_TYPE_P (fld))
367 return false;
368 if (delta)
369 *delta = fld;
370
371 if (TREE_CHAIN (fld))
372 return false;
373
374 return true;
375}
376
be95e2b9
MJ
377/* Go through arguments of the CALL and for every one that looks like a member
378 pointer, check whether it can be safely declared pass-through and if so,
379 mark that to the corresponding item of jump FUNCTIONS. Return true iff
380 there are non-pass-through member pointers within the arguments. INFO
381 describes formal parameters of the caller. */
382
3e293154
MJ
383static bool
384compute_pass_through_member_ptrs (struct ipa_node_params *info,
385 struct ipa_jump_func *functions,
726a989a 386 gimple call)
3e293154 387{
3e293154 388 bool undecided_members = false;
726a989a 389 unsigned num;
3e293154
MJ
390 tree arg;
391
726a989a 392 for (num = 0; num < gimple_call_num_args (call); num++)
3e293154 393 {
726a989a
RB
394 arg = gimple_call_arg (call, num);
395
3e293154 396 if (type_like_member_ptr_p (TREE_TYPE (arg), NULL, NULL))
518dc859 397 {
3e293154
MJ
398 if (TREE_CODE (arg) == PARM_DECL)
399 {
400 int index = ipa_get_param_decl_index (info, arg);
401
402 gcc_assert (index >=0);
f8e2a1ed 403 if (!ipa_is_param_modified (info, index))
3e293154 404 {
133f9369 405 functions[num].type = IPA_JF_PASS_THROUGH;
3e293154
MJ
406 functions[num].value.formal_id = index;
407 }
408 else
409 undecided_members = true;
410 }
411 else
412 undecided_members = true;
518dc859 413 }
3e293154
MJ
414 }
415
416 return undecided_members;
417}
418
419/* Simple function filling in a member pointer constant jump function (with PFN
420 and DELTA as the constant value) into JFUNC. */
be95e2b9 421
3e293154
MJ
422static void
423fill_member_ptr_cst_jump_function (struct ipa_jump_func *jfunc,
424 tree pfn, tree delta)
425{
133f9369 426 jfunc->type = IPA_JF_CONST_MEMBER_PTR;
3e293154
MJ
427 jfunc->value.member_cst.pfn = pfn;
428 jfunc->value.member_cst.delta = delta;
429}
430
7ec49257
MJ
431/* If RHS is an SSA_NAMe and it is defined by a simple copy assign statement,
432 return the rhs of its defining statement. */
433
434static inline tree
435get_ssa_def_if_simple_copy (tree rhs)
436{
437 while (TREE_CODE (rhs) == SSA_NAME && !SSA_NAME_IS_DEFAULT_DEF (rhs))
438 {
439 gimple def_stmt = SSA_NAME_DEF_STMT (rhs);
440
441 if (gimple_assign_single_p (def_stmt))
442 rhs = gimple_assign_rhs1 (def_stmt);
443 }
444 return rhs;
445}
446
726a989a
RB
447/* Traverse statements from CALL backwards, scanning whether the argument ARG
448 which is a member pointer is filled in with constant values. If it is, fill
449 the jump function JFUNC in appropriately. METHOD_FIELD and DELTA_FIELD are
450 fields of the record type of the member pointer. To give an example, we
451 look for a pattern looking like the following:
3e293154
MJ
452
453 D.2515.__pfn ={v} printStuff;
454 D.2515.__delta ={v} 0;
455 i_1 = doprinting (D.2515); */
be95e2b9 456
3e293154 457static void
726a989a 458determine_cst_member_ptr (gimple call, tree arg, tree method_field,
3e293154
MJ
459 tree delta_field, struct ipa_jump_func *jfunc)
460{
726a989a 461 gimple_stmt_iterator gsi;
3e293154
MJ
462 tree method = NULL_TREE;
463 tree delta = NULL_TREE;
464
726a989a 465 gsi = gsi_for_stmt (call);
3e293154 466
726a989a
RB
467 gsi_prev (&gsi);
468 for (; !gsi_end_p (gsi); gsi_prev (&gsi))
3e293154 469 {
726a989a 470 gimple stmt = gsi_stmt (gsi);
3e293154
MJ
471 tree lhs, rhs, fld;
472
8b75fc9b 473 if (!gimple_assign_single_p (stmt))
3e293154
MJ
474 return;
475
726a989a
RB
476 lhs = gimple_assign_lhs (stmt);
477 rhs = gimple_assign_rhs1 (stmt);
3e293154
MJ
478
479 if (TREE_CODE (lhs) != COMPONENT_REF
480 || TREE_OPERAND (lhs, 0) != arg)
481 continue;
482
483 fld = TREE_OPERAND (lhs, 1);
484 if (!method && fld == method_field)
518dc859 485 {
7ec49257 486 rhs = get_ssa_def_if_simple_copy (rhs);
3e293154
MJ
487 if (TREE_CODE (rhs) == ADDR_EXPR
488 && TREE_CODE (TREE_OPERAND (rhs, 0)) == FUNCTION_DECL
489 && TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs, 0))) == METHOD_TYPE)
518dc859 490 {
3e293154
MJ
491 method = TREE_OPERAND (rhs, 0);
492 if (delta)
493 {
00fc2333 494 fill_member_ptr_cst_jump_function (jfunc, rhs, delta);
3e293154
MJ
495 return;
496 }
518dc859 497 }
3e293154
MJ
498 else
499 return;
500 }
501
502 if (!delta && fld == delta_field)
503 {
7ec49257 504 rhs = get_ssa_def_if_simple_copy (rhs);
3e293154
MJ
505 if (TREE_CODE (rhs) == INTEGER_CST)
506 {
507 delta = rhs;
508 if (method)
509 {
00fc2333 510 fill_member_ptr_cst_jump_function (jfunc, rhs, delta);
3e293154
MJ
511 return;
512 }
513 }
514 else
515 return;
516 }
517 }
518
519 return;
520}
521
726a989a
RB
522/* Go through the arguments of the CALL and for every member pointer within
523 tries determine whether it is a constant. If it is, create a corresponding
524 constant jump function in FUNCTIONS which is an array of jump functions
525 associated with the call. */
be95e2b9 526
3e293154
MJ
527static void
528compute_cst_member_ptr_arguments (struct ipa_jump_func *functions,
726a989a 529 gimple call)
3e293154 530{
726a989a 531 unsigned num;
3e293154
MJ
532 tree arg, method_field, delta_field;
533
726a989a 534 for (num = 0; num < gimple_call_num_args (call); num++)
3e293154 535 {
726a989a
RB
536 arg = gimple_call_arg (call, num);
537
133f9369 538 if (functions[num].type == IPA_JF_UNKNOWN
3e293154
MJ
539 && type_like_member_ptr_p (TREE_TYPE (arg), &method_field,
540 &delta_field))
726a989a
RB
541 determine_cst_member_ptr (call, arg, method_field, delta_field,
542 &functions[num]);
3e293154
MJ
543 }
544}
545
546/* Compute jump function for all arguments of callsite CS and insert the
547 information in the jump_functions array in the ipa_edge_args corresponding
548 to this callsite. */
be95e2b9 549
3e293154
MJ
550void
551ipa_compute_jump_functions (struct cgraph_edge *cs)
552{
553 struct ipa_node_params *info = IPA_NODE_REF (cs->caller);
554 struct ipa_edge_args *arguments = IPA_EDGE_REF (cs);
726a989a 555 gimple call;
3e293154
MJ
556
557 if (ipa_get_cs_argument_count (arguments) == 0 || arguments->jump_functions)
558 return;
559 arguments->jump_functions = XCNEWVEC (struct ipa_jump_func,
560 ipa_get_cs_argument_count (arguments));
726a989a
RB
561
562 call = cs->call_stmt;
563 gcc_assert (is_gimple_call (call));
3e293154
MJ
564
565 /* We will deal with constants and SSA scalars first: */
566 compute_scalar_jump_functions (info, arguments->jump_functions, call);
567
568 /* Let's check whether there are any potential member pointers and if so,
569 whether we can determine their functions as pass_through. */
570 if (!compute_pass_through_member_ptrs (info, arguments->jump_functions, call))
571 return;
572
be95e2b9 573 /* Finally, let's check whether we actually pass a new constant member
3e293154 574 pointer here... */
726a989a 575 compute_cst_member_ptr_arguments (arguments->jump_functions, call);
3e293154
MJ
576}
577
578/* If RHS looks like a rhs of a statement loading pfn from a member pointer
579 formal parameter, return the parameter, otherwise return NULL. */
be95e2b9 580
3e293154
MJ
581static tree
582ipa_get_member_ptr_load_param (tree rhs)
583{
584 tree rec, fld;
585 tree ptr_field;
586
587 if (TREE_CODE (rhs) != COMPONENT_REF)
588 return NULL_TREE;
589
590 rec = TREE_OPERAND (rhs, 0);
591 if (TREE_CODE (rec) != PARM_DECL
592 || !type_like_member_ptr_p (TREE_TYPE (rec), &ptr_field, NULL))
593 return NULL_TREE;
594
595 fld = TREE_OPERAND (rhs, 1);
596 if (fld == ptr_field)
597 return rec;
598 else
599 return NULL_TREE;
600}
601
602/* If STMT looks like a statement loading a value from a member pointer formal
be95e2b9
MJ
603 parameter, this function returns that parameter. */
604
3e293154 605static tree
726a989a 606ipa_get_stmt_member_ptr_load_param (gimple stmt)
3e293154
MJ
607{
608 tree rhs;
609
8b75fc9b 610 if (!gimple_assign_single_p (stmt))
3e293154
MJ
611 return NULL_TREE;
612
726a989a 613 rhs = gimple_assign_rhs1 (stmt);
3e293154
MJ
614 return ipa_get_member_ptr_load_param (rhs);
615}
616
617/* Returns true iff T is an SSA_NAME defined by a statement. */
be95e2b9 618
3e293154
MJ
619static bool
620ipa_is_ssa_with_stmt_def (tree t)
621{
622 if (TREE_CODE (t) == SSA_NAME
623 && !SSA_NAME_IS_DEFAULT_DEF (t))
624 return true;
625 else
626 return false;
627}
628
629/* Creates a new note describing a call to a parameter number FORMAL_ID and
630 attaches it to the linked list of INFO. It also sets the called flag of the
631 parameter. STMT is the corresponding call statement. */
be95e2b9 632
3e293154
MJ
633static void
634ipa_note_param_call (struct ipa_node_params *info, int formal_id,
726a989a 635 gimple stmt)
3e293154
MJ
636{
637 struct ipa_param_call_note *note;
726a989a 638 basic_block bb = gimple_bb (stmt);
3e293154 639
f8e2a1ed 640 info->params[formal_id].called = 1;
3e293154
MJ
641
642 note = XCNEW (struct ipa_param_call_note);
643 note->formal_id = formal_id;
644 note->stmt = stmt;
645 note->count = bb->count;
9187e02d 646 note->frequency = compute_call_stmt_bb_frequency (current_function_decl, bb);
3e293154
MJ
647
648 note->next = info->param_calls;
649 info->param_calls = note;
650
651 return;
652}
653
726a989a
RB
654/* Analyze the CALL and examine uses of formal parameters of the caller
655 (described by INFO). Currently it checks whether the call calls a pointer
656 that is a formal parameter and if so, the parameter is marked with the
657 called flag and a note describing the call is created. This is very simple
658 for ordinary pointers represented in SSA but not-so-nice when it comes to
659 member pointers. The ugly part of this function does nothing more than
660 tries to match the pattern of such a call. An example of such a pattern is
661 the gimple dump below, the call is on the last line:
3e293154
MJ
662
663 <bb 2>:
664 f$__delta_5 = f.__delta;
665 f$__pfn_24 = f.__pfn;
666 D.2496_3 = (int) f$__pfn_24;
667 D.2497_4 = D.2496_3 & 1;
668 if (D.2497_4 != 0)
669 goto <bb 3>;
670 else
671 goto <bb 4>;
672
673 <bb 3>:
674 D.2500_7 = (unsigned int) f$__delta_5;
675 D.2501_8 = &S + D.2500_7;
676 D.2502_9 = (int (*__vtbl_ptr_type) (void) * *) D.2501_8;
677 D.2503_10 = *D.2502_9;
678 D.2504_12 = f$__pfn_24 + -1;
679 D.2505_13 = (unsigned int) D.2504_12;
680 D.2506_14 = D.2503_10 + D.2505_13;
681 D.2507_15 = *D.2506_14;
682 iftmp.11_16 = (String:: *) D.2507_15;
683
684 <bb 4>:
685 # iftmp.11_1 = PHI <iftmp.11_16(3), f$__pfn_24(2)>
686 D.2500_19 = (unsigned int) f$__delta_5;
687 D.2508_20 = &S + D.2500_19;
688 D.2493_21 = iftmp.11_1 (D.2508_20, 4);
689
690 Such patterns are results of simple calls to a member pointer:
691
692 int doprinting (int (MyString::* f)(int) const)
693 {
694 MyString S ("somestring");
695
696 return (S.*f)(4);
697 }
698*/
699
700static void
726a989a 701ipa_analyze_call_uses (struct ipa_node_params *info, gimple call)
3e293154 702{
726a989a
RB
703 tree target = gimple_call_fn (call);
704 gimple def;
705 tree var;
3e293154 706 tree n1, n2;
726a989a
RB
707 gimple d1, d2;
708 tree rec, rec2, cond;
709 gimple branch;
3e293154 710 int index;
3e293154
MJ
711 basic_block bb, virt_bb, join;
712
713 if (TREE_CODE (target) != SSA_NAME)
714 return;
715
716 var = SSA_NAME_VAR (target);
717 if (SSA_NAME_IS_DEFAULT_DEF (target))
718 {
719 /* assuming TREE_CODE (var) == PARM_DECL */
720 index = ipa_get_param_decl_index (info, var);
721 if (index >= 0)
726a989a 722 ipa_note_param_call (info, index, call);
3e293154
MJ
723 return;
724 }
725
726 /* Now we need to try to match the complex pattern of calling a member
727 pointer. */
728
729 if (!POINTER_TYPE_P (TREE_TYPE (target))
730 || TREE_CODE (TREE_TYPE (TREE_TYPE (target))) != METHOD_TYPE)
731 return;
732
733 def = SSA_NAME_DEF_STMT (target);
726a989a 734 if (gimple_code (def) != GIMPLE_PHI)
3e293154
MJ
735 return;
736
726a989a 737 if (gimple_phi_num_args (def) != 2)
3e293154
MJ
738 return;
739
740 /* First, we need to check whether one of these is a load from a member
741 pointer that is a parameter to this function. */
742 n1 = PHI_ARG_DEF (def, 0);
743 n2 = PHI_ARG_DEF (def, 1);
1fc8feb5 744 if (!ipa_is_ssa_with_stmt_def (n1) || !ipa_is_ssa_with_stmt_def (n2))
3e293154
MJ
745 return;
746 d1 = SSA_NAME_DEF_STMT (n1);
747 d2 = SSA_NAME_DEF_STMT (n2);
748
749 if ((rec = ipa_get_stmt_member_ptr_load_param (d1)))
750 {
751 if (ipa_get_stmt_member_ptr_load_param (d2))
752 return;
753
726a989a
RB
754 bb = gimple_bb (d1);
755 virt_bb = gimple_bb (d2);
3e293154
MJ
756 }
757 else if ((rec = ipa_get_stmt_member_ptr_load_param (d2)))
758 {
726a989a
RB
759 bb = gimple_bb (d2);
760 virt_bb = gimple_bb (d1);
3e293154
MJ
761 }
762 else
763 return;
764
765 /* Second, we need to check that the basic blocks are laid out in the way
766 corresponding to the pattern. */
767
726a989a 768 join = gimple_bb (def);
3e293154
MJ
769 if (!single_pred_p (virt_bb) || !single_succ_p (virt_bb)
770 || single_pred (virt_bb) != bb
771 || single_succ (virt_bb) != join)
772 return;
773
774 /* Third, let's see that the branching is done depending on the least
775 significant bit of the pfn. */
776
777 branch = last_stmt (bb);
726a989a 778 if (gimple_code (branch) != GIMPLE_COND)
3e293154
MJ
779 return;
780
726a989a
RB
781 if (gimple_cond_code (branch) != NE_EXPR
782 || !integer_zerop (gimple_cond_rhs (branch)))
3e293154 783 return;
3e293154 784
726a989a 785 cond = gimple_cond_lhs (branch);
3e293154
MJ
786 if (!ipa_is_ssa_with_stmt_def (cond))
787 return;
788
726a989a 789 def = SSA_NAME_DEF_STMT (cond);
8b75fc9b 790 if (!is_gimple_assign (def)
726a989a
RB
791 || gimple_assign_rhs_code (def) != BIT_AND_EXPR
792 || !integer_onep (gimple_assign_rhs2 (def)))
3e293154 793 return;
726a989a
RB
794
795 cond = gimple_assign_rhs1 (def);
3e293154
MJ
796 if (!ipa_is_ssa_with_stmt_def (cond))
797 return;
798
726a989a 799 def = SSA_NAME_DEF_STMT (cond);
3e293154 800
8b75fc9b
MJ
801 if (is_gimple_assign (def)
802 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
3e293154 803 {
726a989a 804 cond = gimple_assign_rhs1 (def);
3e293154
MJ
805 if (!ipa_is_ssa_with_stmt_def (cond))
806 return;
726a989a 807 def = SSA_NAME_DEF_STMT (cond);
3e293154
MJ
808 }
809
726a989a 810 rec2 = ipa_get_stmt_member_ptr_load_param (def);
3e293154
MJ
811 if (rec != rec2)
812 return;
813
814 index = ipa_get_param_decl_index (info, rec);
f8e2a1ed 815 if (index >= 0 && !ipa_is_param_modified (info, index))
726a989a 816 ipa_note_param_call (info, index, call);
3e293154
MJ
817
818 return;
819}
820
821/* Analyze the statement STMT with respect to formal parameters (described in
822 INFO) and their uses. Currently it only checks whether formal parameters
823 are called. */
be95e2b9 824
3e293154 825static void
726a989a 826ipa_analyze_stmt_uses (struct ipa_node_params *info, gimple stmt)
3e293154 827{
726a989a
RB
828 if (is_gimple_call (stmt))
829 ipa_analyze_call_uses (info, stmt);
3e293154
MJ
830}
831
832/* Scan the function body of NODE and inspect the uses of formal parameters.
833 Store the findings in various structures of the associated ipa_node_params
834 structure, such as parameter flags, notes etc. */
be95e2b9 835
3e293154
MJ
836void
837ipa_analyze_params_uses (struct cgraph_node *node)
838{
839 tree decl = node->decl;
840 basic_block bb;
841 struct function *func;
726a989a 842 gimple_stmt_iterator gsi;
3e293154
MJ
843 struct ipa_node_params *info = IPA_NODE_REF (node);
844
726a989a 845 if (ipa_get_param_count (info) == 0 || info->uses_analysis_done)
3e293154 846 return;
3e293154
MJ
847
848 func = DECL_STRUCT_FUNCTION (decl);
849 FOR_EACH_BB_FN (bb, func)
850 {
726a989a 851 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3e293154 852 {
726a989a 853 gimple stmt = gsi_stmt (gsi);
3e293154 854 ipa_analyze_stmt_uses (info, stmt);
518dc859 855 }
518dc859 856 }
3e293154
MJ
857
858 info->uses_analysis_done = 1;
859}
860
be95e2b9 861/* Update the jump functions associated with call graph edge E when the call
3e293154
MJ
862 graph edge CS is being inlined, assuming that E->caller is already (possibly
863 indirectly) inlined into CS->callee and that E has not been inlined. */
be95e2b9 864
3e293154
MJ
865static void
866update_jump_functions_after_inlining (struct cgraph_edge *cs,
867 struct cgraph_edge *e)
868{
869 struct ipa_edge_args *top = IPA_EDGE_REF (cs);
870 struct ipa_edge_args *args = IPA_EDGE_REF (e);
871 int count = ipa_get_cs_argument_count (args);
872 int i;
873
874 for (i = 0; i < count; i++)
875 {
876 struct ipa_jump_func *src, *dst = ipa_get_ith_jump_func (args, i);
877
133f9369 878 if (dst->type != IPA_JF_PASS_THROUGH)
3e293154
MJ
879 continue;
880
881 /* We must check range due to calls with variable number of arguments: */
882 if (dst->value.formal_id >= (unsigned) ipa_get_cs_argument_count (top))
883 {
32e8bb8e 884 dst->type = IPA_JF_UNKNOWN;
3e293154
MJ
885 continue;
886 }
887
888 src = ipa_get_ith_jump_func (top, dst->value.formal_id);
889 *dst = *src;
890 }
891}
892
893/* Print out a debug message to file F that we have discovered that an indirect
be95e2b9 894 call described by NT is in fact a call of a known constant function described
3e293154 895 by JFUNC. NODE is the node where the call is. */
be95e2b9 896
3e293154
MJ
897static void
898print_edge_addition_message (FILE *f, struct ipa_param_call_note *nt,
899 struct ipa_jump_func *jfunc,
900 struct cgraph_node *node)
901{
902 fprintf (f, "ipa-prop: Discovered an indirect call to a known target (");
133f9369 903 if (jfunc->type == IPA_JF_CONST_MEMBER_PTR)
3e293154
MJ
904 {
905 print_node_brief (f, "", jfunc->value.member_cst.pfn, 0);
906 print_node_brief (f, ", ", jfunc->value.member_cst.delta, 0);
907 }
908 else
909 print_node_brief(f, "", jfunc->value.constant, 0);
910
911 fprintf (f, ") in %s: ", cgraph_node_name (node));
726a989a 912 print_gimple_stmt (f, nt->stmt, 2, TDF_SLIM);
3e293154
MJ
913}
914
915/* Update the param called notes associated with NODE when CS is being inlined,
916 assuming NODE is (potentially indirectly) inlined into CS->callee.
917 Moreover, if the callee is discovered to be constant, create a new cgraph
e56f5f3e 918 edge for it. Newly discovered indirect edges will be added to *NEW_EDGES,
f8e2a1ed 919 unless NEW_EDGES is NULL. Return true iff a new edge(s) were created. */
be95e2b9 920
f8e2a1ed 921static bool
3e293154
MJ
922update_call_notes_after_inlining (struct cgraph_edge *cs,
923 struct cgraph_node *node,
e56f5f3e 924 VEC (cgraph_edge_p, heap) **new_edges)
3e293154
MJ
925{
926 struct ipa_node_params *info = IPA_NODE_REF (node);
927 struct ipa_edge_args *top = IPA_EDGE_REF (cs);
928 struct ipa_param_call_note *nt;
f8e2a1ed 929 bool res = false;
3e293154
MJ
930
931 for (nt = info->param_calls; nt; nt = nt->next)
932 {
933 struct ipa_jump_func *jfunc;
934
935 if (nt->processed)
936 continue;
937
938 /* We must check range due to calls with variable number of arguments: */
939 if (nt->formal_id >= (unsigned) ipa_get_cs_argument_count (top))
940 {
941 nt->processed = true;
942 continue;
943 }
944
945 jfunc = ipa_get_ith_jump_func (top, nt->formal_id);
133f9369 946 if (jfunc->type == IPA_JF_PASS_THROUGH)
3e293154 947 nt->formal_id = jfunc->value.formal_id;
133f9369
MJ
948 else if (jfunc->type == IPA_JF_CONST
949 || jfunc->type == IPA_JF_CONST_MEMBER_PTR)
3e293154
MJ
950 {
951 struct cgraph_node *callee;
952 struct cgraph_edge *new_indirect_edge;
953 tree decl;
954
955 nt->processed = true;
133f9369 956 if (jfunc->type == IPA_JF_CONST_MEMBER_PTR)
3e293154
MJ
957 decl = jfunc->value.member_cst.pfn;
958 else
959 decl = jfunc->value.constant;
960
00fc2333
JH
961 if (TREE_CODE (decl) != ADDR_EXPR)
962 continue;
963 decl = TREE_OPERAND (decl, 0);
964
3e293154
MJ
965 if (TREE_CODE (decl) != FUNCTION_DECL)
966 continue;
967 callee = cgraph_node (decl);
968 if (!callee || !callee->local.inlinable)
969 continue;
970
f8e2a1ed 971 res = true;
3e293154
MJ
972 if (dump_file)
973 print_edge_addition_message (dump_file, nt, jfunc, node);
974
975 new_indirect_edge = cgraph_create_edge (node, callee, nt->stmt,
976 nt->count, nt->frequency,
977 nt->loop_nest);
978 new_indirect_edge->indirect_call = 1;
979 ipa_check_create_edge_args ();
980 if (new_edges)
e56f5f3e
JJ
981 VEC_safe_push (cgraph_edge_p, heap, *new_edges, new_indirect_edge);
982 top = IPA_EDGE_REF (cs);
3e293154
MJ
983 }
984 }
f8e2a1ed 985 return res;
3e293154
MJ
986}
987
988/* Recursively traverse subtree of NODE (including node) made of inlined
989 cgraph_edges when CS has been inlined and invoke
990 update_call_notes_after_inlining on all nodes and
991 update_jump_functions_after_inlining on all non-inlined edges that lead out
992 of this subtree. Newly discovered indirect edges will be added to
f8e2a1ed
MJ
993 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were
994 created. */
be95e2b9 995
f8e2a1ed 996static bool
3e293154
MJ
997propagate_info_to_inlined_callees (struct cgraph_edge *cs,
998 struct cgraph_node *node,
e56f5f3e 999 VEC (cgraph_edge_p, heap) **new_edges)
3e293154
MJ
1000{
1001 struct cgraph_edge *e;
f8e2a1ed 1002 bool res;
3e293154 1003
f8e2a1ed 1004 res = update_call_notes_after_inlining (cs, node, new_edges);
3e293154
MJ
1005
1006 for (e = node->callees; e; e = e->next_callee)
1007 if (!e->inline_failed)
f8e2a1ed 1008 res |= propagate_info_to_inlined_callees (cs, e->callee, new_edges);
3e293154
MJ
1009 else
1010 update_jump_functions_after_inlining (cs, e);
f8e2a1ed
MJ
1011
1012 return res;
3e293154
MJ
1013}
1014
1015/* Update jump functions and call note functions on inlining the call site CS.
1016 CS is expected to lead to a node already cloned by
1017 cgraph_clone_inline_nodes. Newly discovered indirect edges will be added to
f8e2a1ed
MJ
1018 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were +
1019 created. */
be95e2b9 1020
f8e2a1ed 1021bool
3e293154 1022ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
e56f5f3e 1023 VEC (cgraph_edge_p, heap) **new_edges)
3e293154 1024{
f8e2a1ed
MJ
1025 /* Do nothing if the preparation phase has not been carried out yet
1026 (i.e. during early inlining). */
1027 if (!ipa_node_params_vector)
1028 return false;
1029 gcc_assert (ipa_edge_args_vector);
1030
1031 return propagate_info_to_inlined_callees (cs, cs->callee, new_edges);
518dc859
RL
1032}
1033
771578a0
MJ
1034/* Frees all dynamically allocated structures that the argument info points
1035 to. */
be95e2b9 1036
518dc859 1037void
771578a0 1038ipa_free_edge_args_substructures (struct ipa_edge_args *args)
518dc859 1039{
771578a0
MJ
1040 if (args->jump_functions)
1041 free (args->jump_functions);
1042
1043 memset (args, 0, sizeof (*args));
518dc859
RL
1044}
1045
771578a0 1046/* Free all ipa_edge structures. */
be95e2b9 1047
518dc859 1048void
771578a0 1049ipa_free_all_edge_args (void)
518dc859 1050{
771578a0
MJ
1051 int i;
1052 struct ipa_edge_args *args;
518dc859 1053
771578a0
MJ
1054 for (i = 0;
1055 VEC_iterate (ipa_edge_args_t, ipa_edge_args_vector, i, args);
1056 i++)
1057 ipa_free_edge_args_substructures (args);
1058
1059 VEC_free (ipa_edge_args_t, heap, ipa_edge_args_vector);
1060 ipa_edge_args_vector = NULL;
518dc859
RL
1061}
1062
771578a0
MJ
1063/* Frees all dynamically allocated structures that the param info points
1064 to. */
be95e2b9 1065
518dc859 1066void
771578a0 1067ipa_free_node_params_substructures (struct ipa_node_params *info)
518dc859 1068{
f8e2a1ed
MJ
1069 if (info->params)
1070 free (info->params);
3e293154
MJ
1071
1072 while (info->param_calls)
1073 {
1074 struct ipa_param_call_note *note = info->param_calls;
1075 info->param_calls = note->next;
1076 free (note);
1077 }
771578a0
MJ
1078
1079 memset (info, 0, sizeof (*info));
518dc859
RL
1080}
1081
771578a0 1082/* Free all ipa_node_params structures. */
be95e2b9 1083
518dc859 1084void
771578a0 1085ipa_free_all_node_params (void)
518dc859 1086{
771578a0
MJ
1087 int i;
1088 struct ipa_node_params *info;
518dc859 1089
771578a0
MJ
1090 for (i = 0;
1091 VEC_iterate (ipa_node_params_t, ipa_node_params_vector, i, info);
1092 i++)
1093 ipa_free_node_params_substructures (info);
1094
1095 VEC_free (ipa_node_params_t, heap, ipa_node_params_vector);
1096 ipa_node_params_vector = NULL;
1097}
1098
1099/* Hook that is called by cgraph.c when an edge is removed. */
be95e2b9 1100
771578a0 1101static void
5c0466b5 1102ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
771578a0 1103{
c6f7cfc1
JH
1104 /* During IPA-CP updating we can be called on not-yet analyze clones. */
1105 if (VEC_length (ipa_edge_args_t, ipa_edge_args_vector)
1106 <= (unsigned)cs->uid)
1107 return;
771578a0 1108 ipa_free_edge_args_substructures (IPA_EDGE_REF (cs));
518dc859
RL
1109}
1110
771578a0 1111/* Hook that is called by cgraph.c when a node is removed. */
be95e2b9 1112
771578a0 1113static void
5c0466b5 1114ipa_node_removal_hook (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
771578a0
MJ
1115{
1116 ipa_free_node_params_substructures (IPA_NODE_REF (node));
1117}
1118
1119/* Helper function to duplicate an array of size N that is at SRC and store a
1120 pointer to it to DST. Nothing is done if SRC is NULL. */
be95e2b9 1121
771578a0
MJ
1122static void *
1123duplicate_array (void *src, size_t n)
1124{
1125 void *p;
1126
1127 if (!src)
1128 return NULL;
1129
1130 p = xcalloc (1, n);
1131 memcpy (p, src, n);
1132 return p;
1133}
1134
1135/* Hook that is called by cgraph.c when a node is duplicated. */
be95e2b9 1136
771578a0
MJ
1137static void
1138ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
f8e2a1ed 1139 __attribute__((unused)) void *data)
771578a0
MJ
1140{
1141 struct ipa_edge_args *old_args, *new_args;
1142 int arg_count;
1143
1144 ipa_check_create_edge_args ();
1145
1146 old_args = IPA_EDGE_REF (src);
1147 new_args = IPA_EDGE_REF (dst);
1148
1149 arg_count = ipa_get_cs_argument_count (old_args);
1150 ipa_set_cs_argument_count (new_args, arg_count);
1151 new_args->jump_functions = (struct ipa_jump_func *)
1152 duplicate_array (old_args->jump_functions,
1153 sizeof (struct ipa_jump_func) * arg_count);
771578a0
MJ
1154}
1155
1156/* Hook that is called by cgraph.c when a node is duplicated. */
be95e2b9 1157
771578a0
MJ
1158static void
1159ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
f8e2a1ed 1160 __attribute__((unused)) void *data)
771578a0
MJ
1161{
1162 struct ipa_node_params *old_info, *new_info;
3e293154 1163 struct ipa_param_call_note *note;
771578a0
MJ
1164 int param_count;
1165
1166 ipa_check_create_node_params ();
1167 old_info = IPA_NODE_REF (src);
1168 new_info = IPA_NODE_REF (dst);
1169 param_count = ipa_get_param_count (old_info);
1170
1171 ipa_set_param_count (new_info, param_count);
f8e2a1ed
MJ
1172 new_info->params = (struct ipa_param_descriptor *)
1173 duplicate_array (old_info->params,
1174 sizeof (struct ipa_param_descriptor) * param_count);
771578a0
MJ
1175 new_info->ipcp_orig_node = old_info->ipcp_orig_node;
1176 new_info->count_scale = old_info->count_scale;
1177
3e293154
MJ
1178 for (note = old_info->param_calls; note; note = note->next)
1179 {
1180 struct ipa_param_call_note *nn;
1181
1182 nn = (struct ipa_param_call_note *)
1183 xcalloc (1, sizeof (struct ipa_param_call_note));
1184 memcpy (nn, note, sizeof (struct ipa_param_call_note));
1185 nn->next = new_info->param_calls;
1186 new_info->param_calls = nn;
1187 }
771578a0
MJ
1188}
1189
1190/* Register our cgraph hooks if they are not already there. */
be95e2b9 1191
518dc859 1192void
771578a0 1193ipa_register_cgraph_hooks (void)
518dc859 1194{
771578a0
MJ
1195 if (!edge_removal_hook_holder)
1196 edge_removal_hook_holder =
1197 cgraph_add_edge_removal_hook (&ipa_edge_removal_hook, NULL);
1198 if (!node_removal_hook_holder)
1199 node_removal_hook_holder =
1200 cgraph_add_node_removal_hook (&ipa_node_removal_hook, NULL);
1201 if (!edge_duplication_hook_holder)
1202 edge_duplication_hook_holder =
1203 cgraph_add_edge_duplication_hook (&ipa_edge_duplication_hook, NULL);
1204 if (!node_duplication_hook_holder)
1205 node_duplication_hook_holder =
1206 cgraph_add_node_duplication_hook (&ipa_node_duplication_hook, NULL);
1207}
518dc859 1208
771578a0 1209/* Unregister our cgraph hooks if they are not already there. */
be95e2b9 1210
771578a0
MJ
1211static void
1212ipa_unregister_cgraph_hooks (void)
1213{
1214 cgraph_remove_edge_removal_hook (edge_removal_hook_holder);
1215 edge_removal_hook_holder = NULL;
1216 cgraph_remove_node_removal_hook (node_removal_hook_holder);
1217 node_removal_hook_holder = NULL;
1218 cgraph_remove_edge_duplication_hook (edge_duplication_hook_holder);
1219 edge_duplication_hook_holder = NULL;
1220 cgraph_remove_node_duplication_hook (node_duplication_hook_holder);
1221 node_duplication_hook_holder = NULL;
1222}
1223
1224/* Free all ipa_node_params and all ipa_edge_args structures if they are no
1225 longer needed after ipa-cp. */
be95e2b9 1226
771578a0
MJ
1227void
1228free_all_ipa_structures_after_ipa_cp (void)
3e293154 1229{
7e8b322a 1230 if (!flag_indirect_inlining)
3e293154
MJ
1231 {
1232 ipa_free_all_edge_args ();
1233 ipa_free_all_node_params ();
1234 ipa_unregister_cgraph_hooks ();
1235 }
1236}
1237
1238/* Free all ipa_node_params and all ipa_edge_args structures if they are no
1239 longer needed after indirect inlining. */
be95e2b9 1240
3e293154
MJ
1241void
1242free_all_ipa_structures_after_iinln (void)
771578a0
MJ
1243{
1244 ipa_free_all_edge_args ();
1245 ipa_free_all_node_params ();
1246 ipa_unregister_cgraph_hooks ();
518dc859
RL
1247}
1248
dcd416e3 1249/* Print ipa_tree_map data structures of all functions in the
518dc859 1250 callgraph to F. */
be95e2b9 1251
518dc859 1252void
ca30a539 1253ipa_print_node_params (FILE * f, struct cgraph_node *node)
518dc859
RL
1254{
1255 int i, count;
1256 tree temp;
3e293154 1257 struct ipa_node_params *info;
518dc859 1258
3e293154
MJ
1259 if (!node->analyzed)
1260 return;
1261 info = IPA_NODE_REF (node);
ca30a539 1262 fprintf (f, " function %s Trees :: \n", cgraph_node_name (node));
3e293154
MJ
1263 count = ipa_get_param_count (info);
1264 for (i = 0; i < count; i++)
518dc859 1265 {
f8e2a1ed 1266 temp = ipa_get_param (info, i);
ca30a539
JH
1267 if (TREE_CODE (temp) == PARM_DECL)
1268 fprintf (f, " param %d : %s", i,
1269 (*lang_hooks.decl_printable_name) (temp, 2));
f8e2a1ed 1270 if (ipa_is_param_modified (info, i))
3e293154 1271 fprintf (f, " modified");
f8e2a1ed 1272 if (ipa_is_param_called (info, i))
3e293154
MJ
1273 fprintf (f, " called");
1274 fprintf (f, "\n");
518dc859
RL
1275 }
1276}
dcd416e3 1277
ca30a539 1278/* Print ipa_tree_map data structures of all functions in the
3e293154 1279 callgraph to F. */
be95e2b9 1280
3e293154 1281void
ca30a539 1282ipa_print_all_params (FILE * f)
3e293154
MJ
1283{
1284 struct cgraph_node *node;
1285
ca30a539 1286 fprintf (f, "\nFunction parameters:\n");
3e293154 1287 for (node = cgraph_nodes; node; node = node->next)
ca30a539 1288 ipa_print_node_params (f, node);
3e293154 1289}