Mercurial > hg > CbC > CbC_gcc
comparison gcc/ipa-cp.c @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | 3bfb6c00c1e0 |
children | b7f97abdc517 |
comparison
equal
deleted
inserted
replaced
52:c156f1bd5cd9 | 55:77e2b8dfacca |
---|---|
1 /* Interprocedural constant propagation | 1 /* Interprocedural constant propagation |
2 Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc. | 2 Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. |
3 Contributed by Razya Ladelsky <RAZYA@il.ibm.com> | 3 Contributed by Razya Ladelsky <RAZYA@il.ibm.com> |
4 | 4 |
5 This file is part of GCC. | 5 This file is part of GCC. |
6 | 6 |
7 GCC is free software; you can redistribute it and/or modify it under | 7 GCC is free software; you can redistribute it and/or modify it under |
8 the terms of the GNU General Public License as published by the Free | 8 the terms of the GNU General Public License as published by the Free |
9 Software Foundation; either version 3, or (at your option) any later | 9 Software Foundation; either version 3, or (at your option) any later |
10 version. | 10 version. |
11 | 11 |
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | 12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or | 13 WARRANTY; without even the implied warranty of MERCHANTABILITY or |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | 14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
15 for more details. | 15 for more details. |
16 | 16 |
17 You should have received a copy of the GNU General Public License | 17 You should have received a copy of the GNU General Public License |
18 along with GCC; see the file COPYING3. If not see | 18 along with GCC; see the file COPYING3. If not see |
19 <http://www.gnu.org/licenses/>. */ | 19 <http://www.gnu.org/licenses/>. */ |
20 | 20 |
21 /* Interprocedural constant propagation. The aim of interprocedural constant | 21 /* Interprocedural constant propagation. The aim of interprocedural constant |
25 | 25 |
26 int g (int y) | 26 int g (int y) |
27 { | 27 { |
28 printf ("value is %d",y); | 28 printf ("value is %d",y); |
29 } | 29 } |
30 | 30 |
31 int f (int x) | 31 int f (int x) |
32 { | 32 { |
33 g (x); | 33 g (x); |
34 } | 34 } |
35 | 35 |
41 void main (void) | 41 void main (void) |
42 { | 42 { |
43 f (3); | 43 f (3); |
44 h (3); | 44 h (3); |
45 } | 45 } |
46 | 46 |
47 | 47 |
48 The IPCP algorithm will find that g's formal argument y is always called | 48 The IPCP algorithm will find that g's formal argument y is always called |
49 with the value 3. | 49 with the value 3. |
50 | 50 |
51 The algorithm used is based on "Interprocedural Constant Propagation", by | 51 The algorithm used is based on "Interprocedural Constant Propagation", by |
52 Challahan David, Keith D Cooper, Ken Kennedy, Linda Torczon, Comp86, pg | 52 Challahan David, Keith D Cooper, Ken Kennedy, Linda Torczon, Comp86, pg |
53 152-161 | 53 152-161 |
54 | 54 |
55 The optimization is divided into three stages: | 55 The optimization is divided into three stages: |
56 | 56 |
57 First stage - intraprocedural analysis | 57 First stage - intraprocedural analysis |
58 ======================================= | 58 ======================================= |
59 This phase computes jump_function and modification flags. | 59 This phase computes jump_function and modification flags. |
60 | 60 |
61 A jump function for a callsite represents the values passed as an actual | 61 A jump function for a callsite represents the values passed as an actual |
62 arguments of a given callsite. There are three types of values: | 62 arguments of a given callsite. There are three types of values: |
63 Pass through - the caller's formal parameter is passed as an actual argument. | 63 Pass through - the caller's formal parameter is passed as an actual argument. |
64 Constant - a constant is passed as an actual argument. | 64 Constant - a constant is passed as an actual argument. |
65 Unknown - neither of the above. | 65 Unknown - neither of the above. |
66 | 66 |
67 The jump function info, ipa_jump_func, is stored in ipa_edge_args | 67 The jump function info, ipa_jump_func, is stored in ipa_edge_args |
68 structure (defined in ipa_prop.h and pointed to by cgraph_node->aux) | 68 structure (defined in ipa_prop.h and pointed to by cgraph_node->aux) |
69 modified_flags are defined in ipa_node_params structure | 69 modified_flags are defined in ipa_node_params structure |
70 (defined in ipa_prop.h and pointed to by cgraph_edge->aux). | 70 (defined in ipa_prop.h and pointed to by cgraph_edge->aux). |
71 | 71 |
72 -ipcp_init_stage() is the first stage driver. | 72 -ipcp_init_stage() is the first stage driver. |
73 | 73 |
74 Second stage - interprocedural analysis | 74 Second stage - interprocedural analysis |
75 ======================================== | 75 ======================================== |
76 This phase does the interprocedural constant propagation. | 76 This phase does the interprocedural constant propagation. |
77 It computes lattices for all formal parameters in the program | 77 It computes lattices for all formal parameters in the program |
78 and their value that may be: | 78 and their value that may be: |
79 TOP - unknown. | 79 TOP - unknown. |
80 BOTTOM - non constant. | 80 BOTTOM - non constant. |
81 CONSTANT - constant value. | 81 CONSTANT - constant value. |
82 | 82 |
83 Lattice describing a formal parameter p will have a constant value if all | 83 Lattice describing a formal parameter p will have a constant value if all |
84 callsites invoking this function have the same constant value passed to p. | 84 callsites invoking this function have the same constant value passed to p. |
85 | 85 |
86 The lattices are stored in ipcp_lattice which is itself in ipa_node_params | 86 The lattices are stored in ipcp_lattice which is itself in ipa_node_params |
87 structure (defined in ipa_prop.h and pointed to by cgraph_edge->aux). | 87 structure (defined in ipa_prop.h and pointed to by cgraph_edge->aux). |
88 | 88 |
89 -ipcp_iterate_stage() is the second stage driver. | 89 -ipcp_iterate_stage() is the second stage driver. |
90 | 90 |
113 during a traversal of the call graph, during which all callsites are | 113 during a traversal of the call graph, during which all callsites are |
114 redirected to call the cloned function. Then the callsites are traversed | 114 redirected to call the cloned function. Then the callsites are traversed |
115 and many calls redirected back to fit the description above. | 115 and many calls redirected back to fit the description above. |
116 | 116 |
117 -ipcp_insert_stage() is the third phase driver. | 117 -ipcp_insert_stage() is the third phase driver. |
118 | 118 |
119 */ | 119 */ |
120 | 120 |
121 #include "config.h" | 121 #include "config.h" |
122 #include "system.h" | 122 #include "system.h" |
123 #include "coretypes.h" | 123 #include "coretypes.h" |
184 | 184 |
185 ipa_initialize_node_params (node); | 185 ipa_initialize_node_params (node); |
186 ipa_detect_param_modifications (node); | 186 ipa_detect_param_modifications (node); |
187 } | 187 } |
188 | 188 |
189 /* Recompute all local information since node might've got new | |
190 direct calls after cloning. */ | |
191 static void | |
192 ipcp_update_cloned_node (struct cgraph_node *new_node) | |
193 { | |
194 basic_block bb; | |
195 gimple_stmt_iterator gsi; | |
196 | |
197 /* We might've introduced new direct calls. */ | |
198 push_cfun (DECL_STRUCT_FUNCTION (new_node->decl)); | |
199 current_function_decl = new_node->decl; | |
200 | |
201 FOR_EACH_BB (bb) | |
202 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) | |
203 { | |
204 gimple stmt = gsi_stmt (gsi); | |
205 tree decl; | |
206 | |
207 if (is_gimple_call (stmt) | |
208 && (decl = gimple_call_fndecl (stmt)) | |
209 && !cgraph_edge (new_node, stmt)) | |
210 { | |
211 struct cgraph_edge *new_edge; | |
212 | |
213 new_edge = cgraph_create_edge (new_node, cgraph_node (decl), stmt, | |
214 bb->count, | |
215 compute_call_stmt_bb_frequency (bb), | |
216 bb->loop_depth); | |
217 new_edge->indirect_call = 1; | |
218 } | |
219 } | |
220 | |
221 /* Indirect inlinng rely on fact that we've already analyzed | |
222 the body.. */ | |
223 if (flag_indirect_inlining) | |
224 { | |
225 struct cgraph_edge *cs; | |
226 | |
227 ipcp_analyze_node (new_node); | |
228 | |
229 for (cs = new_node->callees; cs; cs = cs->next_callee) | |
230 { | |
231 ipa_count_arguments (cs); | |
232 ipa_compute_jump_functions (cs); | |
233 } | |
234 } | |
235 pop_cfun (); | |
236 current_function_decl = NULL; | |
237 } | |
238 | |
239 /* Return scale for NODE. */ | 189 /* Return scale for NODE. */ |
240 static inline gcov_type | 190 static inline gcov_type |
241 ipcp_get_node_scale (struct cgraph_node *node) | 191 ipcp_get_node_scale (struct cgraph_node *node) |
242 { | 192 { |
243 return IPA_NODE_REF (node)->count_scale; | 193 return IPA_NODE_REF (node)->count_scale; |
330 pass-through jump functions can be evaluated. */ | 280 pass-through jump functions can be evaluated. */ |
331 static void | 281 static void |
332 ipcp_lattice_from_jfunc (struct ipa_node_params *info, struct ipcp_lattice *lat, | 282 ipcp_lattice_from_jfunc (struct ipa_node_params *info, struct ipcp_lattice *lat, |
333 struct ipa_jump_func *jfunc) | 283 struct ipa_jump_func *jfunc) |
334 { | 284 { |
335 if (jfunc->type == IPA_CONST) | 285 if (jfunc->type == IPA_JF_CONST) |
336 { | 286 { |
337 lat->type = IPA_CONST_VALUE; | 287 lat->type = IPA_CONST_VALUE; |
338 lat->constant = jfunc->value.constant; | 288 lat->constant = jfunc->value.constant; |
339 } | 289 } |
340 else if (jfunc->type == IPA_PASS_THROUGH) | 290 else if (jfunc->type == IPA_JF_PASS_THROUGH) |
341 { | 291 { |
342 struct ipcp_lattice *caller_lat; | 292 struct ipcp_lattice *caller_lat; |
343 | 293 tree cst; |
344 caller_lat = ipcp_get_lattice (info, jfunc->value.formal_id); | 294 |
295 caller_lat = ipcp_get_lattice (info, jfunc->value.pass_through.formal_id); | |
345 lat->type = caller_lat->type; | 296 lat->type = caller_lat->type; |
346 lat->constant = caller_lat->constant; | 297 if (caller_lat->type != IPA_CONST_VALUE) |
298 return; | |
299 cst = caller_lat->constant; | |
300 | |
301 if (jfunc->value.pass_through.operation != NOP_EXPR) | |
302 { | |
303 tree restype; | |
304 if (TREE_CODE_CLASS (jfunc->value.pass_through.operation) | |
305 == tcc_comparison) | |
306 restype = boolean_type_node; | |
307 else | |
308 restype = TREE_TYPE (cst); | |
309 cst = fold_binary (jfunc->value.pass_through.operation, | |
310 restype, cst, jfunc->value.pass_through.operand); | |
311 } | |
312 if (!cst || !is_gimple_ip_invariant (cst)) | |
313 lat->type = IPA_BOTTOM; | |
314 lat->constant = cst; | |
315 } | |
316 else if (jfunc->type == IPA_JF_ANCESTOR) | |
317 { | |
318 struct ipcp_lattice *caller_lat; | |
319 tree t; | |
320 bool ok; | |
321 | |
322 caller_lat = ipcp_get_lattice (info, jfunc->value.ancestor.formal_id); | |
323 lat->type = caller_lat->type; | |
324 if (caller_lat->type != IPA_CONST_VALUE) | |
325 return; | |
326 if (TREE_CODE (caller_lat->constant) != ADDR_EXPR) | |
327 { | |
328 /* This can happen when the constant is a NULL pointer. */ | |
329 lat->type = IPA_BOTTOM; | |
330 return; | |
331 } | |
332 t = TREE_OPERAND (caller_lat->constant, 0); | |
333 ok = build_ref_for_offset (&t, TREE_TYPE (t), | |
334 jfunc->value.ancestor.offset, | |
335 jfunc->value.ancestor.type, false); | |
336 if (!ok) | |
337 { | |
338 lat->type = IPA_BOTTOM; | |
339 lat->constant = NULL_TREE; | |
340 } | |
341 else | |
342 lat->constant = build_fold_addr_expr (t); | |
347 } | 343 } |
348 else | 344 else |
349 lat->type = IPA_BOTTOM; | 345 lat->type = IPA_BOTTOM; |
350 } | 346 } |
351 | 347 |
399 fprintf (f, "type is BOTTOM\n"); | 395 fprintf (f, "type is BOTTOM\n"); |
400 } | 396 } |
401 } | 397 } |
402 } | 398 } |
403 | 399 |
400 /* Return true if ipcp algorithms would allow cloning NODE. */ | |
401 | |
402 static bool | |
403 ipcp_versionable_function_p (struct cgraph_node *node) | |
404 { | |
405 tree decl = node->decl; | |
406 basic_block bb; | |
407 | |
408 /* There are a number of generic reasons functions cannot be versioned. */ | |
409 if (!tree_versionable_function_p (decl)) | |
410 return false; | |
411 | |
412 /* Removing arguments doesn't work if the function takes varargs. */ | |
413 if (DECL_STRUCT_FUNCTION (decl)->stdarg) | |
414 return false; | |
415 | |
416 /* Removing arguments doesn't work if we use __builtin_apply_args. */ | |
417 FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (decl)) | |
418 { | |
419 gimple_stmt_iterator gsi; | |
420 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) | |
421 { | |
422 const_gimple stmt = gsi_stmt (gsi); | |
423 tree t; | |
424 | |
425 if (!is_gimple_call (stmt)) | |
426 continue; | |
427 t = gimple_call_fndecl (stmt); | |
428 if (t == NULL_TREE) | |
429 continue; | |
430 if (DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL | |
431 && DECL_FUNCTION_CODE (t) == BUILT_IN_APPLY_ARGS) | |
432 return false; | |
433 } | |
434 } | |
435 | |
436 return true; | |
437 } | |
438 | |
404 /* Return true if this NODE is viable candidate for cloning. */ | 439 /* Return true if this NODE is viable candidate for cloning. */ |
405 static bool | 440 static bool |
406 ipcp_cloning_candidate_p (struct cgraph_node *node) | 441 ipcp_cloning_candidate_p (struct cgraph_node *node) |
407 { | 442 { |
408 int n_calls = 0; | 443 int n_calls = 0; |
412 | 447 |
413 /* We never clone functions that are not visible from outside. | 448 /* We never clone functions that are not visible from outside. |
414 FIXME: in future we should clone such functions when they are called with | 449 FIXME: in future we should clone such functions when they are called with |
415 different constants, but current ipcp implementation is not good on this. | 450 different constants, but current ipcp implementation is not good on this. |
416 */ | 451 */ |
417 if (!node->needed || !node->analyzed) | 452 if (cgraph_only_called_directly_p (node) || !node->analyzed) |
418 return false; | 453 return false; |
419 | 454 |
420 if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE) | 455 if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE) |
421 { | 456 { |
422 if (dump_file) | 457 if (dump_file) |
423 fprintf (dump_file, "Not considering %s for cloning; body is overwrittable.\n", | 458 fprintf (dump_file, "Not considering %s for cloning; body is overwrittable.\n", |
424 cgraph_node_name (node)); | 459 cgraph_node_name (node)); |
425 return false; | 460 return false; |
426 } | 461 } |
427 if (!tree_versionable_function_p (node->decl)) | 462 if (!ipcp_versionable_function_p (node)) |
428 { | 463 { |
429 if (dump_file) | 464 if (dump_file) |
430 fprintf (dump_file, "Not considering %s for cloning; body is not versionable.\n", | 465 fprintf (dump_file, "Not considering %s for cloning; body is not versionable.\n", |
431 cgraph_node_name (node)); | 466 cgraph_node_name (node)); |
432 return false; | 467 return false; |
436 direct_call_sum += e->count; | 471 direct_call_sum += e->count; |
437 n_calls ++; | 472 n_calls ++; |
438 if (cgraph_maybe_hot_edge_p (e)) | 473 if (cgraph_maybe_hot_edge_p (e)) |
439 n_hot_calls ++; | 474 n_hot_calls ++; |
440 } | 475 } |
441 | 476 |
442 if (!n_calls) | 477 if (!n_calls) |
443 { | 478 { |
444 if (dump_file) | 479 if (dump_file) |
445 fprintf (dump_file, "Not considering %s for cloning; no direct calls.\n", | 480 fprintf (dump_file, "Not considering %s for cloning; no direct calls.\n", |
446 cgraph_node_name (node)); | 481 cgraph_node_name (node)); |
447 return false; | 482 return false; |
448 } | 483 } |
449 if (node->local.inline_summary.self_insns < n_calls) | 484 if (node->local.inline_summary.self_size < n_calls) |
450 { | 485 { |
451 if (dump_file) | 486 if (dump_file) |
452 fprintf (dump_file, "Considering %s for cloning; code would shrink.\n", | 487 fprintf (dump_file, "Considering %s for cloning; code would shrink.\n", |
453 cgraph_node_name (node)); | 488 cgraph_node_name (node)); |
454 return true; | 489 return true; |
455 } | 490 } |
456 | 491 |
457 if (!flag_ipa_cp_clone) | 492 if (!flag_ipa_cp_clone) |
458 { | 493 { |
459 if (dump_file) | 494 if (dump_file) |
460 fprintf (dump_file, "Not considering %s for cloning; -fipa-cp-clone disabled.\n", | 495 fprintf (dump_file, "Not considering %s for cloning; -fipa-cp-clone disabled.\n", |
506 struct ipa_node_params *info = IPA_NODE_REF (node); | 541 struct ipa_node_params *info = IPA_NODE_REF (node); |
507 enum ipa_lattice_type type; | 542 enum ipa_lattice_type type; |
508 | 543 |
509 if (ipa_is_called_with_var_arguments (info)) | 544 if (ipa_is_called_with_var_arguments (info)) |
510 type = IPA_BOTTOM; | 545 type = IPA_BOTTOM; |
511 else if (!node->needed) | 546 else if (cgraph_only_called_directly_p (node)) |
512 type = IPA_TOP; | 547 type = IPA_TOP; |
513 /* When cloning is allowed, we can assume that externally visible functions | 548 /* When cloning is allowed, we can assume that externally visible functions |
514 are not called. We will compensate this by cloning later. */ | 549 are not called. We will compensate this by cloning later. */ |
515 else if (ipcp_cloning_candidate_p (node)) | 550 else if (ipcp_cloning_candidate_p (node)) |
516 type = IPA_TOP, n_cloning_candidates ++; | 551 type = IPA_TOP, n_cloning_candidates ++; |
541 return val; | 576 return val; |
542 } | 577 } |
543 | 578 |
544 /* Compute the proper scale for NODE. It is the ratio between the number of | 579 /* Compute the proper scale for NODE. It is the ratio between the number of |
545 direct calls (represented on the incoming cgraph_edges) and sum of all | 580 direct calls (represented on the incoming cgraph_edges) and sum of all |
546 invocations of NODE (represented as count in cgraph_node). */ | 581 invocations of NODE (represented as count in cgraph_node). |
582 | |
583 FIXME: This code is wrong. Since the callers can be also clones and | |
584 the clones are not scaled yet, the sums gets unrealistically high. | |
585 To properly compute the counts, we would need to do propagation across | |
586 callgraph (as external call to A might imply call to non-clonned B | |
587 if A's clone calls clonned B). */ | |
547 static void | 588 static void |
548 ipcp_compute_node_scale (struct cgraph_node *node) | 589 ipcp_compute_node_scale (struct cgraph_node *node) |
549 { | 590 { |
550 gcov_type sum; | 591 gcov_type sum; |
551 struct cgraph_edge *cs; | 592 struct cgraph_edge *cs; |
552 | 593 |
553 sum = 0; | 594 sum = 0; |
554 /* Compute sum of all counts of callers. */ | 595 /* Compute sum of all counts of callers. */ |
555 for (cs = node->callers; cs != NULL; cs = cs->next_caller) | 596 for (cs = node->callers; cs != NULL; cs = cs->next_caller) |
556 sum += cs->count; | 597 sum += cs->count; |
598 /* Work around the unrealistically high sum problem. We just don't want | |
599 the non-cloned body to have negative or very low frequency. Since | |
600 majority of execution time will be spent in clones anyway, this should | |
601 give good enough profile. */ | |
602 if (sum > node->count * 9 / 10) | |
603 sum = node->count * 9 / 10; | |
557 if (node->count == 0) | 604 if (node->count == 0) |
558 ipcp_set_node_scale (node, 0); | 605 ipcp_set_node_scale (node, 0); |
559 else | 606 else |
560 ipcp_set_node_scale (node, sum * REG_BR_PROB_BASE / node->count); | 607 ipcp_set_node_scale (node, sum * REG_BR_PROB_BASE / node->count); |
561 } | 608 } |
577 if (!node->analyzed) | 624 if (!node->analyzed) |
578 continue; | 625 continue; |
579 /* building jump functions */ | 626 /* building jump functions */ |
580 for (cs = node->callees; cs; cs = cs->next_callee) | 627 for (cs = node->callees; cs; cs = cs->next_callee) |
581 { | 628 { |
582 if (!cs->callee->analyzed) | 629 /* We do not need to bother analyzing calls to unknown |
630 functions unless they may become known during lto/whopr. */ | |
631 if (!cs->callee->analyzed && !flag_lto && !flag_whopr) | |
583 continue; | 632 continue; |
584 ipa_count_arguments (cs); | 633 ipa_count_arguments (cs); |
585 if (ipa_get_cs_argument_count (IPA_EDGE_REF (cs)) | 634 if (ipa_get_cs_argument_count (IPA_EDGE_REF (cs)) |
586 != ipa_get_param_count (IPA_NODE_REF (cs->callee))) | 635 != ipa_get_param_count (IPA_NODE_REF (cs->callee))) |
587 { | 636 { |
588 /* Handle cases of functions with | 637 /* Handle cases of functions with |
589 a variable number of parameters. */ | 638 a variable number of parameters. */ |
590 ipa_set_called_with_variable_arg (IPA_NODE_REF (cs->callee)); | 639 ipa_set_called_with_variable_arg (IPA_NODE_REF (cs->callee)); |
591 if (flag_indirect_inlining) | 640 if (flag_indirect_inlining) |
592 ipa_compute_jump_functions (cs); | 641 ipa_compute_jump_functions (cs); |
593 } | 642 } |
659 for (cs = node->callees; cs; cs = cs->next_callee) | 708 for (cs = node->callees; cs; cs = cs->next_callee) |
660 { | 709 { |
661 struct ipa_node_params *callee_info = IPA_NODE_REF (cs->callee); | 710 struct ipa_node_params *callee_info = IPA_NODE_REF (cs->callee); |
662 struct ipa_edge_args *args = IPA_EDGE_REF (cs); | 711 struct ipa_edge_args *args = IPA_EDGE_REF (cs); |
663 | 712 |
664 if (ipa_is_called_with_var_arguments (callee_info)) | 713 if (ipa_is_called_with_var_arguments (callee_info) |
714 || !cs->callee->analyzed | |
715 || ipa_is_called_with_var_arguments (callee_info)) | |
665 continue; | 716 continue; |
666 | 717 |
667 count = ipa_get_cs_argument_count (args); | 718 count = ipa_get_cs_argument_count (args); |
668 for (i = 0; i < count; i++) | 719 for (i = 0; i < count; i++) |
669 { | 720 { |
690 struct cgraph_node *node; | 741 struct cgraph_node *node; |
691 n_cloning_candidates = 0; | 742 n_cloning_candidates = 0; |
692 | 743 |
693 if (dump_file) | 744 if (dump_file) |
694 fprintf (dump_file, "\nIPA iterate stage:\n\n"); | 745 fprintf (dump_file, "\nIPA iterate stage:\n\n"); |
746 | |
747 if (in_lto_p) | |
748 ipa_update_after_lto_read (); | |
749 | |
695 for (node = cgraph_nodes; node; node = node->next) | 750 for (node = cgraph_nodes; node; node = node->next) |
696 { | 751 { |
697 ipcp_initialize_node_lattices (node); | 752 ipcp_initialize_node_lattices (node); |
698 ipcp_compute_node_scale (node); | 753 ipcp_compute_node_scale (node); |
699 } | 754 } |
725 static inline bool | 780 static inline bool |
726 ipcp_node_modifiable_p (struct cgraph_node *node) | 781 ipcp_node_modifiable_p (struct cgraph_node *node) |
727 { | 782 { |
728 /* Once we will be able to do in-place replacement, we can be more | 783 /* Once we will be able to do in-place replacement, we can be more |
729 lax here. */ | 784 lax here. */ |
730 return tree_versionable_function_p (node->decl); | 785 return ipcp_versionable_function_p (node); |
731 } | 786 } |
732 | 787 |
733 /* Print count scale data structures. */ | 788 /* Print count scale data structures. */ |
734 static void | 789 static void |
735 ipcp_function_scale_print (FILE * f) | 790 ipcp_function_scale_print (FILE * f) |
777 (HOST_WIDE_INT) cs->count); | 832 (HOST_WIDE_INT) cs->count); |
778 } | 833 } |
779 } | 834 } |
780 } | 835 } |
781 | 836 |
782 /* Print all counts and probabilities of cfg edges of all functions. */ | |
783 static void | |
784 ipcp_print_edge_profiles (FILE * f) | |
785 { | |
786 struct cgraph_node *node; | |
787 basic_block bb; | |
788 edge_iterator ei; | |
789 edge e; | |
790 | |
791 for (node = cgraph_nodes; node; node = node->next) | |
792 { | |
793 fprintf (f, "function %s: \n", cgraph_node_name (node)); | |
794 if (node->analyzed) | |
795 { | |
796 bb = | |
797 ENTRY_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION (node->decl)); | |
798 fprintf (f, "ENTRY: "); | |
799 fprintf (f, " " HOST_WIDE_INT_PRINT_DEC | |
800 " %d\n", (HOST_WIDE_INT) bb->count, bb->frequency); | |
801 | |
802 if (bb->succs) | |
803 FOR_EACH_EDGE (e, ei, bb->succs) | |
804 { | |
805 if (e->dest == | |
806 EXIT_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION | |
807 (node->decl))) | |
808 fprintf (f, "edge ENTRY -> EXIT, Count"); | |
809 else | |
810 fprintf (f, "edge ENTRY -> %d, Count", e->dest->index); | |
811 fprintf (f, " " HOST_WIDE_INT_PRINT_DEC | |
812 " Prob %d\n", (HOST_WIDE_INT) e->count, | |
813 e->probability); | |
814 } | |
815 FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (node->decl)) | |
816 { | |
817 fprintf (f, "bb[%d]: ", bb->index); | |
818 fprintf (f, " " HOST_WIDE_INT_PRINT_DEC | |
819 " %d\n", (HOST_WIDE_INT) bb->count, bb->frequency); | |
820 FOR_EACH_EDGE (e, ei, bb->succs) | |
821 { | |
822 if (e->dest == | |
823 EXIT_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION | |
824 (node->decl))) | |
825 fprintf (f, "edge %d -> EXIT, Count", e->src->index); | |
826 else | |
827 fprintf (f, "edge %d -> %d, Count", e->src->index, | |
828 e->dest->index); | |
829 fprintf (f, " " HOST_WIDE_INT_PRINT_DEC " Prob %d\n", | |
830 (HOST_WIDE_INT) e->count, e->probability); | |
831 } | |
832 } | |
833 } | |
834 } | |
835 } | |
836 | |
837 /* Print counts and frequencies for all basic blocks of all functions. */ | |
838 static void | |
839 ipcp_print_bb_profiles (FILE * f) | |
840 { | |
841 basic_block bb; | |
842 struct cgraph_node *node; | |
843 | |
844 for (node = cgraph_nodes; node; node = node->next) | |
845 { | |
846 fprintf (f, "function %s: \n", cgraph_node_name (node)); | |
847 if (node->analyzed) | |
848 { | |
849 bb = | |
850 ENTRY_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION (node->decl)); | |
851 fprintf (f, "ENTRY: Count"); | |
852 fprintf (f, " " HOST_WIDE_INT_PRINT_DEC | |
853 " Frequency %d\n", (HOST_WIDE_INT) bb->count, | |
854 bb->frequency); | |
855 | |
856 FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (node->decl)) | |
857 { | |
858 fprintf (f, "bb[%d]: Count", bb->index); | |
859 fprintf (f, " " HOST_WIDE_INT_PRINT_DEC | |
860 " Frequency %d\n", (HOST_WIDE_INT) bb->count, | |
861 bb->frequency); | |
862 } | |
863 bb = | |
864 EXIT_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION (node->decl)); | |
865 fprintf (f, "EXIT: Count"); | |
866 fprintf (f, " " HOST_WIDE_INT_PRINT_DEC | |
867 " Frequency %d\n", (HOST_WIDE_INT) bb->count, | |
868 bb->frequency); | |
869 | |
870 } | |
871 } | |
872 } | |
873 | |
874 /* Print profile info for all functions. */ | 837 /* Print profile info for all functions. */ |
875 static void | 838 static void |
876 ipcp_print_profile_data (FILE * f) | 839 ipcp_print_profile_data (FILE * f) |
877 { | 840 { |
878 fprintf (f, "\nNODE COUNTS :\n"); | 841 fprintf (f, "\nNODE COUNTS :\n"); |
879 ipcp_print_func_profile_counts (f); | 842 ipcp_print_func_profile_counts (f); |
880 fprintf (f, "\nCS COUNTS stage:\n"); | 843 fprintf (f, "\nCS COUNTS stage:\n"); |
881 ipcp_print_call_profile_counts (f); | 844 ipcp_print_call_profile_counts (f); |
882 fprintf (f, "\nBB COUNTS and FREQUENCIES :\n"); | |
883 ipcp_print_bb_profiles (f); | |
884 fprintf (f, "\nCFG EDGES COUNTS and PROBABILITIES :\n"); | |
885 ipcp_print_edge_profiles (f); | |
886 } | 845 } |
887 | 846 |
888 /* Build and initialize ipa_replace_map struct according to LAT. This struct is | 847 /* Build and initialize ipa_replace_map struct according to LAT. This struct is |
889 processed by versioning, which operates according to the flags set. | 848 processed by versioning, which operates according to the flags set. |
890 PARM_TREE is the formal parameter found to be constant. LAT represents the | 849 PARM_TREE is the formal parameter found to be constant. LAT represents the |
893 ipcp_create_replace_map (tree parm_tree, struct ipcp_lattice *lat) | 852 ipcp_create_replace_map (tree parm_tree, struct ipcp_lattice *lat) |
894 { | 853 { |
895 struct ipa_replace_map *replace_map; | 854 struct ipa_replace_map *replace_map; |
896 tree const_val; | 855 tree const_val; |
897 | 856 |
898 replace_map = XCNEW (struct ipa_replace_map); | 857 replace_map = GGC_NEW (struct ipa_replace_map); |
899 const_val = build_const_val (lat, TREE_TYPE (parm_tree)); | 858 const_val = build_const_val (lat, TREE_TYPE (parm_tree)); |
900 if (dump_file) | 859 if (dump_file) |
901 { | 860 { |
902 fprintf (dump_file, " replacing param "); | 861 fprintf (dump_file, " replacing param "); |
903 print_generic_expr (dump_file, parm_tree, 0); | 862 print_generic_expr (dump_file, parm_tree, 0); |
937 { | 896 { |
938 struct ipcp_lattice *lat = ipcp_get_lattice (orig_callee_info, i); | 897 struct ipcp_lattice *lat = ipcp_get_lattice (orig_callee_info, i); |
939 if (ipcp_lat_is_const (lat)) | 898 if (ipcp_lat_is_const (lat)) |
940 { | 899 { |
941 jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i); | 900 jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i); |
942 if (jump_func->type != IPA_CONST) | 901 if (jump_func->type != IPA_JF_CONST) |
943 return true; | 902 return true; |
944 } | 903 } |
945 } | 904 } |
946 | 905 |
947 return false; | 906 return false; |
980 bitmap_set_bit (args_to_skip, i); | 939 bitmap_set_bit (args_to_skip, i); |
981 } | 940 } |
982 for (cs = node->callers; cs; cs = next) | 941 for (cs = node->callers; cs; cs = next) |
983 { | 942 { |
984 next = cs->next_caller; | 943 next = cs->next_caller; |
985 if (!cs->indirect_call | 944 if (!ipcp_node_is_clone (cs->caller) && ipcp_need_redirect_p (cs)) |
986 && (ipcp_node_is_clone (cs->caller) | 945 cgraph_redirect_edge_callee (cs, orig_node); |
987 || !ipcp_need_redirect_p (cs))) | |
988 { | |
989 gimple new_stmt; | |
990 gimple_stmt_iterator gsi; | |
991 | |
992 current_function_decl = cs->caller->decl; | |
993 push_cfun (DECL_STRUCT_FUNCTION (cs->caller->decl)); | |
994 | |
995 new_stmt = gimple_call_copy_skip_args (cs->call_stmt, | |
996 args_to_skip); | |
997 gsi = gsi_for_stmt (cs->call_stmt); | |
998 gsi_replace (&gsi, new_stmt, true); | |
999 cgraph_set_call_stmt (cs, new_stmt); | |
1000 pop_cfun (); | |
1001 current_function_decl = NULL; | |
1002 } | |
1003 else | |
1004 { | |
1005 cgraph_redirect_edge_callee (cs, orig_node); | |
1006 gimple_call_set_fndecl (cs->call_stmt, orig_node->decl); | |
1007 } | |
1008 } | 946 } |
1009 } | 947 } |
1010 } | |
1011 | |
1012 /* Update all cfg basic blocks in NODE according to SCALE. */ | |
1013 static void | |
1014 ipcp_update_bb_counts (struct cgraph_node *node, gcov_type scale) | |
1015 { | |
1016 basic_block bb; | |
1017 | |
1018 FOR_ALL_BB_FN (bb, DECL_STRUCT_FUNCTION (node->decl)) | |
1019 bb->count = bb->count * scale / REG_BR_PROB_BASE; | |
1020 } | |
1021 | |
1022 /* Update all cfg edges in NODE according to SCALE. */ | |
1023 static void | |
1024 ipcp_update_edges_counts (struct cgraph_node *node, gcov_type scale) | |
1025 { | |
1026 basic_block bb; | |
1027 edge_iterator ei; | |
1028 edge e; | |
1029 | |
1030 FOR_ALL_BB_FN (bb, DECL_STRUCT_FUNCTION (node->decl)) | |
1031 FOR_EACH_EDGE (e, ei, bb->succs) | |
1032 e->count = e->count * scale / REG_BR_PROB_BASE; | |
1033 } | 948 } |
1034 | 949 |
1035 /* Update profiling info for versioned functions and the functions they were | 950 /* Update profiling info for versioned functions and the functions they were |
1036 versioned from. */ | 951 versioned from. */ |
1037 static void | 952 static void |
1053 orig_node->count * scale_complement / REG_BR_PROB_BASE; | 968 orig_node->count * scale_complement / REG_BR_PROB_BASE; |
1054 for (cs = node->callees; cs; cs = cs->next_callee) | 969 for (cs = node->callees; cs; cs = cs->next_callee) |
1055 cs->count = cs->count * scale / REG_BR_PROB_BASE; | 970 cs->count = cs->count * scale / REG_BR_PROB_BASE; |
1056 for (cs = orig_node->callees; cs; cs = cs->next_callee) | 971 for (cs = orig_node->callees; cs; cs = cs->next_callee) |
1057 cs->count = cs->count * scale_complement / REG_BR_PROB_BASE; | 972 cs->count = cs->count * scale_complement / REG_BR_PROB_BASE; |
1058 ipcp_update_bb_counts (node, scale); | |
1059 ipcp_update_bb_counts (orig_node, scale_complement); | |
1060 ipcp_update_edges_counts (node, scale); | |
1061 ipcp_update_edges_counts (orig_node, scale_complement); | |
1062 } | 973 } |
1063 } | 974 } |
1064 } | 975 } |
1065 | 976 |
1066 /* If NODE was cloned, how much would program grow? */ | 977 /* If NODE was cloned, how much would program grow? */ |
1068 ipcp_estimate_growth (struct cgraph_node *node) | 979 ipcp_estimate_growth (struct cgraph_node *node) |
1069 { | 980 { |
1070 struct cgraph_edge *cs; | 981 struct cgraph_edge *cs; |
1071 int redirectable_node_callers = 0; | 982 int redirectable_node_callers = 0; |
1072 int removable_args = 0; | 983 int removable_args = 0; |
1073 bool need_original = node->needed; | 984 bool need_original = !cgraph_only_called_directly_p (node); |
1074 struct ipa_node_params *info; | 985 struct ipa_node_params *info; |
1075 int i, count; | 986 int i, count; |
1076 int growth; | 987 int growth; |
1077 | 988 |
1078 for (cs = node->callers; cs != NULL; cs = cs->next_caller) | 989 for (cs = node->callers; cs != NULL; cs = cs->next_caller) |
1105 | 1016 |
1106 /* We make just very simple estimate of savings for removal of operand from | 1017 /* We make just very simple estimate of savings for removal of operand from |
1107 call site. Precise cost is dificult to get, as our size metric counts | 1018 call site. Precise cost is dificult to get, as our size metric counts |
1108 constants and moves as free. Generally we are looking for cases that | 1019 constants and moves as free. Generally we are looking for cases that |
1109 small function is called very many times. */ | 1020 small function is called very many times. */ |
1110 growth = node->local.inline_summary.self_insns | 1021 growth = node->local.inline_summary.self_size |
1111 - removable_args * redirectable_node_callers; | 1022 - removable_args * redirectable_node_callers; |
1112 if (growth < 0) | 1023 if (growth < 0) |
1113 return 0; | 1024 return 0; |
1114 return growth; | 1025 return growth; |
1115 } | 1026 } |
1145 cost /= count_sum * 1000 / max_count + 1; | 1056 cost /= count_sum * 1000 / max_count + 1; |
1146 else | 1057 else |
1147 cost /= freq_sum * 1000 / REG_BR_PROB_BASE + 1; | 1058 cost /= freq_sum * 1000 / REG_BR_PROB_BASE + 1; |
1148 if (dump_file) | 1059 if (dump_file) |
1149 fprintf (dump_file, "Cost of versioning %s is %i, (size: %i, freq: %i)\n", | 1060 fprintf (dump_file, "Cost of versioning %s is %i, (size: %i, freq: %i)\n", |
1150 cgraph_node_name (node), cost, node->local.inline_summary.self_insns, | 1061 cgraph_node_name (node), cost, node->local.inline_summary.self_size, |
1151 freq_sum); | 1062 freq_sum); |
1152 return cost + 1; | 1063 return cost + 1; |
1153 } | 1064 } |
1154 | 1065 |
1155 /* Return number of live constant parameters. */ | 1066 /* Return number of live constant parameters. */ |
1181 ipcp_insert_stage (void) | 1092 ipcp_insert_stage (void) |
1182 { | 1093 { |
1183 struct cgraph_node *node, *node1 = NULL; | 1094 struct cgraph_node *node, *node1 = NULL; |
1184 int i; | 1095 int i; |
1185 VEC (cgraph_edge_p, heap) * redirect_callers; | 1096 VEC (cgraph_edge_p, heap) * redirect_callers; |
1186 varray_type replace_trees; | 1097 VEC (ipa_replace_map_p,gc)* replace_trees; |
1187 int node_callers, count; | 1098 int node_callers, count; |
1188 tree parm_tree; | 1099 tree parm_tree; |
1189 struct ipa_replace_map *replace_param; | 1100 struct ipa_replace_map *replace_param; |
1190 fibheap_t heap; | 1101 fibheap_t heap; |
1191 long overall_insns = 0, new_insns = 0; | 1102 long overall_size = 0, new_size = 0; |
1192 long max_new_insns; | 1103 long max_new_size; |
1193 | 1104 |
1194 ipa_check_create_node_params (); | 1105 ipa_check_create_node_params (); |
1195 ipa_check_create_edge_args (); | 1106 ipa_check_create_edge_args (); |
1196 if (dump_file) | 1107 if (dump_file) |
1197 fprintf (dump_file, "\nIPA insert stage:\n\n"); | 1108 fprintf (dump_file, "\nIPA insert stage:\n\n"); |
1201 for (node = cgraph_nodes; node; node = node->next) | 1112 for (node = cgraph_nodes; node; node = node->next) |
1202 if (node->analyzed) | 1113 if (node->analyzed) |
1203 { | 1114 { |
1204 if (node->count > max_count) | 1115 if (node->count > max_count) |
1205 max_count = node->count; | 1116 max_count = node->count; |
1206 overall_insns += node->local.inline_summary.self_insns; | 1117 overall_size += node->local.inline_summary.self_size; |
1207 } | 1118 } |
1208 | 1119 |
1209 max_new_insns = overall_insns; | 1120 max_new_size = overall_size; |
1210 if (max_new_insns < PARAM_VALUE (PARAM_LARGE_UNIT_INSNS)) | 1121 if (max_new_size < PARAM_VALUE (PARAM_LARGE_UNIT_INSNS)) |
1211 max_new_insns = PARAM_VALUE (PARAM_LARGE_UNIT_INSNS); | 1122 max_new_size = PARAM_VALUE (PARAM_LARGE_UNIT_INSNS); |
1212 max_new_insns = max_new_insns * PARAM_VALUE (PARAM_IPCP_UNIT_GROWTH) / 100 + 1; | 1123 max_new_size = max_new_size * PARAM_VALUE (PARAM_IPCP_UNIT_GROWTH) / 100 + 1; |
1213 | 1124 |
1214 /* First collect all functions we proved to have constant arguments to heap. */ | 1125 /* First collect all functions we proved to have constant arguments to heap. */ |
1215 heap = fibheap_new (); | 1126 heap = fibheap_new (); |
1216 for (node = cgraph_nodes; node; node = node->next) | 1127 for (node = cgraph_nodes; node; node = node->next) |
1217 { | 1128 { |
1241 fprintf (dump_file, "considering function %s\n", | 1152 fprintf (dump_file, "considering function %s\n", |
1242 cgraph_node_name (node)); | 1153 cgraph_node_name (node)); |
1243 | 1154 |
1244 growth = ipcp_estimate_growth (node); | 1155 growth = ipcp_estimate_growth (node); |
1245 | 1156 |
1246 if (new_insns + growth > max_new_insns) | 1157 if (new_size + growth > max_new_size) |
1247 break; | 1158 break; |
1248 if (growth | 1159 if (growth |
1249 && optimize_function_for_size_p (DECL_STRUCT_FUNCTION (node->decl))) | 1160 && optimize_function_for_size_p (DECL_STRUCT_FUNCTION (node->decl))) |
1250 { | 1161 { |
1251 if (dump_file) | 1162 if (dump_file) |
1252 fprintf (dump_file, "Not versioning, cold code would grow"); | 1163 fprintf (dump_file, "Not versioning, cold code would grow"); |
1253 continue; | 1164 continue; |
1254 } | 1165 } |
1255 | 1166 |
1256 new_insns += growth; | 1167 new_size += growth; |
1257 | 1168 |
1258 /* Look if original function becomes dead after clonning. */ | 1169 /* Look if original function becomes dead after clonning. */ |
1259 for (cs = node->callers; cs != NULL; cs = cs->next_caller) | 1170 for (cs = node->callers; cs != NULL; cs = cs->next_caller) |
1260 if (cs->caller == node || ipcp_need_redirect_p (cs)) | 1171 if (cs->caller == node || ipcp_need_redirect_p (cs)) |
1261 break; | 1172 break; |
1262 if (!cs && !node->needed) | 1173 if (!cs && cgraph_only_called_directly_p (node)) |
1263 bitmap_set_bit (dead_nodes, node->uid); | 1174 bitmap_set_bit (dead_nodes, node->uid); |
1264 | 1175 |
1265 info = IPA_NODE_REF (node); | 1176 info = IPA_NODE_REF (node); |
1266 count = ipa_get_param_count (info); | 1177 count = ipa_get_param_count (info); |
1267 | 1178 |
1268 VARRAY_GENERIC_PTR_INIT (replace_trees, ipcp_const_param_count (node), | 1179 replace_trees = VEC_alloc (ipa_replace_map_p, gc, 1); |
1269 "replace_trees"); | 1180 args_to_skip = BITMAP_GGC_ALLOC (); |
1270 args_to_skip = BITMAP_ALLOC (NULL); | |
1271 for (i = 0; i < count; i++) | 1181 for (i = 0; i < count; i++) |
1272 { | 1182 { |
1273 struct ipcp_lattice *lat = ipcp_get_lattice (info, i); | 1183 struct ipcp_lattice *lat = ipcp_get_lattice (info, i); |
1274 parm_tree = ipa_get_param (info, i); | 1184 parm_tree = ipa_get_param (info, i); |
1275 | 1185 |
1284 | 1194 |
1285 if (lat->type == IPA_CONST_VALUE) | 1195 if (lat->type == IPA_CONST_VALUE) |
1286 { | 1196 { |
1287 replace_param = | 1197 replace_param = |
1288 ipcp_create_replace_map (parm_tree, lat); | 1198 ipcp_create_replace_map (parm_tree, lat); |
1289 VARRAY_PUSH_GENERIC_PTR (replace_trees, replace_param); | 1199 VEC_safe_push (ipa_replace_map_p, gc, replace_trees, replace_param); |
1290 bitmap_set_bit (args_to_skip, i); | 1200 bitmap_set_bit (args_to_skip, i); |
1291 } | 1201 } |
1292 } | 1202 } |
1293 | 1203 |
1294 /* Compute how many callers node has. */ | 1204 /* Compute how many callers node has. */ |
1300 VEC_quick_push (cgraph_edge_p, redirect_callers, cs); | 1210 VEC_quick_push (cgraph_edge_p, redirect_callers, cs); |
1301 | 1211 |
1302 /* Redirecting all the callers of the node to the | 1212 /* Redirecting all the callers of the node to the |
1303 new versioned node. */ | 1213 new versioned node. */ |
1304 node1 = | 1214 node1 = |
1305 cgraph_function_versioning (node, redirect_callers, replace_trees, | 1215 cgraph_create_virtual_clone (node, redirect_callers, replace_trees, |
1306 args_to_skip); | 1216 args_to_skip); |
1307 BITMAP_FREE (args_to_skip); | 1217 args_to_skip = NULL; |
1308 VEC_free (cgraph_edge_p, heap, redirect_callers); | 1218 VEC_free (cgraph_edge_p, heap, redirect_callers); |
1309 VARRAY_CLEAR (replace_trees); | 1219 replace_trees = NULL; |
1220 | |
1310 if (node1 == NULL) | 1221 if (node1 == NULL) |
1311 continue; | 1222 continue; |
1312 if (dump_file) | 1223 if (dump_file) |
1313 fprintf (dump_file, "versioned function %s with growth %i, overall %i\n", | 1224 fprintf (dump_file, "versioned function %s with growth %i, overall %i\n", |
1314 cgraph_node_name (node), (int)growth, (int)new_insns); | 1225 cgraph_node_name (node), (int)growth, (int)new_size); |
1315 ipcp_init_cloned_node (node, node1); | 1226 ipcp_init_cloned_node (node, node1); |
1316 | 1227 |
1317 /* We've possibly introduced direct calls. */ | 1228 /* TODO: We can use indirect inlning info to produce new calls. */ |
1318 ipcp_update_cloned_node (node1); | |
1319 | 1229 |
1320 if (dump_file) | 1230 if (dump_file) |
1321 dump_function_to_file (node1->decl, dump_file, dump_flags); | 1231 dump_function_to_file (node1->decl, dump_file, dump_flags); |
1322 | 1232 |
1323 for (cs = node->callees; cs; cs = cs->next_callee) | 1233 for (cs = node->callees; cs; cs = cs->next_callee) |
1379 if (dump_file) | 1289 if (dump_file) |
1380 fprintf (dump_file, "\nIPA constant propagation start:\n"); | 1290 fprintf (dump_file, "\nIPA constant propagation start:\n"); |
1381 ipa_check_create_node_params (); | 1291 ipa_check_create_node_params (); |
1382 ipa_check_create_edge_args (); | 1292 ipa_check_create_edge_args (); |
1383 ipa_register_cgraph_hooks (); | 1293 ipa_register_cgraph_hooks (); |
1384 /* 1. Call the init stage to initialize | 1294 /* 1. Call the init stage to initialize |
1385 the ipa_node_params and ipa_edge_args structures. */ | 1295 the ipa_node_params and ipa_edge_args structures. */ |
1386 ipcp_init_stage (); | 1296 ipcp_init_stage (); |
1297 } | |
1298 | |
1299 /* Write ipcp summary for nodes in SET. */ | |
1300 static void | |
1301 ipcp_write_summary (cgraph_node_set set) | |
1302 { | |
1303 ipa_prop_write_jump_functions (set); | |
1304 } | |
1305 | |
1306 /* Read ipcp summary. */ | |
1307 static void | |
1308 ipcp_read_summary (void) | |
1309 { | |
1310 ipa_prop_read_jump_functions (); | |
1387 } | 1311 } |
1388 | 1312 |
1389 /* Gate for IPCP optimization. */ | 1313 /* Gate for IPCP optimization. */ |
1390 static bool | 1314 static bool |
1391 cgraph_gate_cp (void) | 1315 cgraph_gate_cp (void) |
1392 { | 1316 { |
1393 return flag_ipa_cp; | 1317 return flag_ipa_cp; |
1394 } | 1318 } |
1395 | 1319 |
1396 struct ipa_opt_pass pass_ipa_cp = | 1320 struct ipa_opt_pass_d pass_ipa_cp = |
1397 { | 1321 { |
1398 { | 1322 { |
1399 IPA_PASS, | 1323 IPA_PASS, |
1400 "cp", /* name */ | 1324 "cp", /* name */ |
1401 cgraph_gate_cp, /* gate */ | 1325 cgraph_gate_cp, /* gate */ |
1403 NULL, /* sub */ | 1327 NULL, /* sub */ |
1404 NULL, /* next */ | 1328 NULL, /* next */ |
1405 0, /* static_pass_number */ | 1329 0, /* static_pass_number */ |
1406 TV_IPA_CONSTANT_PROP, /* tv_id */ | 1330 TV_IPA_CONSTANT_PROP, /* tv_id */ |
1407 0, /* properties_required */ | 1331 0, /* properties_required */ |
1408 PROP_trees, /* properties_provided */ | 1332 0, /* properties_provided */ |
1409 0, /* properties_destroyed */ | 1333 0, /* properties_destroyed */ |
1410 0, /* todo_flags_start */ | 1334 0, /* todo_flags_start */ |
1411 TODO_dump_cgraph | TODO_dump_func | | 1335 TODO_dump_cgraph | TODO_dump_func | |
1412 TODO_remove_functions /* todo_flags_finish */ | 1336 TODO_remove_functions /* todo_flags_finish */ |
1413 }, | 1337 }, |
1414 ipcp_generate_summary, /* generate_summary */ | 1338 ipcp_generate_summary, /* generate_summary */ |
1415 NULL, /* write_summary */ | 1339 ipcp_write_summary, /* write_summary */ |
1416 NULL, /* read_summary */ | 1340 ipcp_read_summary, /* read_summary */ |
1417 NULL, /* function_read_summary */ | 1341 NULL, /* function_read_summary */ |
1342 lto_ipa_fixup_call_notes, /* stmt_fixup */ | |
1418 0, /* TODOs */ | 1343 0, /* TODOs */ |
1419 NULL, /* function_transform */ | 1344 NULL, /* function_transform */ |
1420 NULL, /* variable_transform */ | 1345 NULL, /* variable_transform */ |
1421 }; | 1346 }; |