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