Mercurial > hg > CbC > CbC_gcc
comparison gcc/ipa-cp.c @ 63:b7f97abdc517 gcc-4.6-20100522
update gcc from gcc-4.5.0 to gcc-4.6
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 24 May 2010 12:47:05 +0900 |
parents | 77e2b8dfacca |
children | f6334be47118 |
comparison
equal
deleted
inserted
replaced
56:3c8a44c06a95 | 63:b7f97abdc517 |
---|---|
1 /* Interprocedural constant propagation | 1 /* Interprocedural constant propagation |
2 Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. | 2 Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 |
3 Free Software Foundation, Inc. | |
3 Contributed by Razya Ladelsky <RAZYA@il.ibm.com> | 4 Contributed by Razya Ladelsky <RAZYA@il.ibm.com> |
4 | 5 |
5 This file is part of GCC. | 6 This file is part of GCC. |
6 | 7 |
7 GCC is free software; you can redistribute it and/or modify it under | 8 GCC is free software; you can redistribute it and/or modify it under |
128 #include "tree-flow.h" | 129 #include "tree-flow.h" |
129 #include "tree-pass.h" | 130 #include "tree-pass.h" |
130 #include "flags.h" | 131 #include "flags.h" |
131 #include "timevar.h" | 132 #include "timevar.h" |
132 #include "diagnostic.h" | 133 #include "diagnostic.h" |
134 #include "tree-pretty-print.h" | |
133 #include "tree-dump.h" | 135 #include "tree-dump.h" |
134 #include "tree-inline.h" | 136 #include "tree-inline.h" |
135 #include "fibheap.h" | 137 #include "fibheap.h" |
136 #include "params.h" | 138 #include "params.h" |
137 | 139 |
180 ipcp_analyze_node (struct cgraph_node *node) | 182 ipcp_analyze_node (struct cgraph_node *node) |
181 { | 183 { |
182 /* Unreachable nodes should have been eliminated before ipcp. */ | 184 /* Unreachable nodes should have been eliminated before ipcp. */ |
183 gcc_assert (node->needed || node->reachable); | 185 gcc_assert (node->needed || node->reachable); |
184 | 186 |
187 node->local.versionable = tree_versionable_function_p (node->decl); | |
185 ipa_initialize_node_params (node); | 188 ipa_initialize_node_params (node); |
186 ipa_detect_param_modifications (node); | 189 ipa_detect_param_modifications (node); |
187 } | 190 } |
188 | 191 |
189 /* Return scale for NODE. */ | 192 /* Return scale for NODE. */ |
224 { | 227 { |
225 gcc_assert (ipcp_lat_is_const (lat1) && ipcp_lat_is_const (lat2)); | 228 gcc_assert (ipcp_lat_is_const (lat1) && ipcp_lat_is_const (lat2)); |
226 if (lat1->type != lat2->type) | 229 if (lat1->type != lat2->type) |
227 return false; | 230 return false; |
228 | 231 |
229 if (operand_equal_p (lat1->constant, lat2->constant, 0)) | 232 if (TREE_CODE (lat1->constant) == ADDR_EXPR |
230 return true; | 233 && TREE_CODE (lat2->constant) == ADDR_EXPR |
231 | 234 && TREE_CODE (TREE_OPERAND (lat1->constant, 0)) == CONST_DECL |
232 return false; | 235 && TREE_CODE (TREE_OPERAND (lat2->constant, 0)) == CONST_DECL) |
236 return operand_equal_p (DECL_INITIAL (TREE_OPERAND (lat1->constant, 0)), | |
237 DECL_INITIAL (TREE_OPERAND (lat2->constant, 0)), 0); | |
238 else | |
239 return operand_equal_p (lat1->constant, lat2->constant, 0); | |
233 } | 240 } |
234 | 241 |
235 /* Compute Meet arithmetics: | 242 /* Compute Meet arithmetics: |
236 Meet (IPA_BOTTOM, x) = IPA_BOTTOM | 243 Meet (IPA_BOTTOM, x) = IPA_BOTTOM |
237 Meet (IPA_TOP,x) = x | 244 Meet (IPA_TOP,x) = x |
383 struct ipcp_lattice *lat = ipcp_get_lattice (info, i); | 390 struct ipcp_lattice *lat = ipcp_get_lattice (info, i); |
384 | 391 |
385 fprintf (f, " param [%d]: ", i); | 392 fprintf (f, " param [%d]: ", i); |
386 if (lat->type == IPA_CONST_VALUE) | 393 if (lat->type == IPA_CONST_VALUE) |
387 { | 394 { |
395 tree cst = lat->constant; | |
388 fprintf (f, "type is CONST "); | 396 fprintf (f, "type is CONST "); |
389 print_generic_expr (f, lat->constant, 0); | 397 print_generic_expr (f, cst, 0); |
398 if (TREE_CODE (cst) == ADDR_EXPR | |
399 && TREE_CODE (TREE_OPERAND (cst, 0)) == CONST_DECL) | |
400 { | |
401 fprintf (f, " -> "); | |
402 print_generic_expr (f, DECL_INITIAL (TREE_OPERAND (cst, 0)), | |
403 0); | |
404 } | |
390 fprintf (f, "\n"); | 405 fprintf (f, "\n"); |
391 } | 406 } |
392 else if (lat->type == IPA_TOP) | 407 else if (lat->type == IPA_TOP) |
393 fprintf (f, "type is TOP\n"); | 408 fprintf (f, "type is TOP\n"); |
394 else | 409 else |
400 /* Return true if ipcp algorithms would allow cloning NODE. */ | 415 /* Return true if ipcp algorithms would allow cloning NODE. */ |
401 | 416 |
402 static bool | 417 static bool |
403 ipcp_versionable_function_p (struct cgraph_node *node) | 418 ipcp_versionable_function_p (struct cgraph_node *node) |
404 { | 419 { |
405 tree decl = node->decl; | 420 struct cgraph_edge *edge; |
406 basic_block bb; | |
407 | 421 |
408 /* There are a number of generic reasons functions cannot be versioned. */ | 422 /* There are a number of generic reasons functions cannot be versioned. */ |
409 if (!tree_versionable_function_p (decl)) | 423 if (!node->local.versionable) |
410 return false; | 424 return false; |
411 | 425 |
412 /* Removing arguments doesn't work if the function takes varargs. */ | 426 /* Removing arguments doesn't work if the function takes varargs |
413 if (DECL_STRUCT_FUNCTION (decl)->stdarg) | 427 or use __builtin_apply_args. */ |
414 return false; | 428 for (edge = node->callees; edge; edge = edge->next_callee) |
415 | 429 { |
416 /* Removing arguments doesn't work if we use __builtin_apply_args. */ | 430 tree t = edge->callee->decl; |
417 FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (decl)) | 431 if (DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL |
418 { | 432 && (DECL_FUNCTION_CODE (t) == BUILT_IN_APPLY_ARGS |
419 gimple_stmt_iterator gsi; | 433 || DECL_FUNCTION_CODE (t) == BUILT_IN_VA_START)) |
420 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) | 434 return false; |
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 } |
435 | 436 |
436 return true; | 437 return true; |
437 } | 438 } |
438 | 439 |
612 propagated later on. */ | 613 propagated later on. */ |
613 static void | 614 static void |
614 ipcp_init_stage (void) | 615 ipcp_init_stage (void) |
615 { | 616 { |
616 struct cgraph_node *node; | 617 struct cgraph_node *node; |
617 struct cgraph_edge *cs; | |
618 | 618 |
619 for (node = cgraph_nodes; node; node = node->next) | 619 for (node = cgraph_nodes; node; node = node->next) |
620 if (node->analyzed) | 620 if (node->analyzed) |
621 ipcp_analyze_node (node); | 621 ipcp_analyze_node (node); |
622 for (node = cgraph_nodes; node; node = node->next) | 622 for (node = cgraph_nodes; node; node = node->next) |
623 { | 623 { |
624 if (!node->analyzed) | 624 if (!node->analyzed) |
625 continue; | 625 continue; |
626 | |
627 ipa_analyze_params_uses (node); | |
626 /* building jump functions */ | 628 /* building jump functions */ |
627 for (cs = node->callees; cs; cs = cs->next_callee) | 629 ipa_compute_jump_functions (node); |
628 { | |
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) | |
632 continue; | |
633 ipa_count_arguments (cs); | |
634 if (ipa_get_cs_argument_count (IPA_EDGE_REF (cs)) | |
635 != ipa_get_param_count (IPA_NODE_REF (cs->callee))) | |
636 { | |
637 /* Handle cases of functions with | |
638 a variable number of parameters. */ | |
639 ipa_set_called_with_variable_arg (IPA_NODE_REF (cs->callee)); | |
640 if (flag_indirect_inlining) | |
641 ipa_compute_jump_functions (cs); | |
642 } | |
643 else | |
644 ipa_compute_jump_functions (cs); | |
645 } | |
646 } | 630 } |
647 } | 631 } |
648 | 632 |
649 /* Return true if there are some formal parameters whose value is IPA_TOP (in | 633 /* Return true if there are some formal parameters whose value is IPA_TOP (in |
650 the whole compilation unit). Change their values to IPA_BOTTOM, since they | 634 the whole compilation unit). Change their values to IPA_BOTTOM, since they |
922 struct cgraph_edge *cs, *next; | 906 struct cgraph_edge *cs, *next; |
923 | 907 |
924 for (i = 0; i < count; i++) | 908 for (i = 0; i < count; i++) |
925 { | 909 { |
926 struct ipcp_lattice *lat = ipcp_get_lattice (info, i); | 910 struct ipcp_lattice *lat = ipcp_get_lattice (info, i); |
927 tree parm_tree = ipa_get_param (info, i); | |
928 | 911 |
929 /* We can proactively remove obviously unused arguments. */ | 912 /* We can proactively remove obviously unused arguments. */ |
930 if (is_gimple_reg (parm_tree) | 913 if (!ipa_is_param_used (info, i)) |
931 && !gimple_default_def (DECL_STRUCT_FUNCTION (orig_node->decl), | |
932 parm_tree)) | |
933 { | 914 { |
934 bitmap_set_bit (args_to_skip, i); | 915 bitmap_set_bit (args_to_skip, i); |
935 continue; | 916 continue; |
936 } | 917 } |
937 | 918 |
1000 info = IPA_NODE_REF (node); | 981 info = IPA_NODE_REF (node); |
1001 count = ipa_get_param_count (info); | 982 count = ipa_get_param_count (info); |
1002 for (i = 0; i < count; i++) | 983 for (i = 0; i < count; i++) |
1003 { | 984 { |
1004 struct ipcp_lattice *lat = ipcp_get_lattice (info, i); | 985 struct ipcp_lattice *lat = ipcp_get_lattice (info, i); |
1005 tree parm_tree = ipa_get_param (info, i); | |
1006 | 986 |
1007 /* We can proactively remove obviously unused arguments. */ | 987 /* We can proactively remove obviously unused arguments. */ |
1008 if (is_gimple_reg (parm_tree) | 988 if (!ipa_is_param_used (info, i)) |
1009 && !gimple_default_def (DECL_STRUCT_FUNCTION (node->decl), | |
1010 parm_tree)) | |
1011 removable_args++; | 989 removable_args++; |
1012 | 990 |
1013 if (lat->type == IPA_CONST_VALUE) | 991 if (lat->type == IPA_CONST_VALUE) |
1014 removable_args++; | 992 removable_args++; |
1015 } | 993 } |
1073 int i; | 1051 int i; |
1074 | 1052 |
1075 for (i = 0; i < count; i++) | 1053 for (i = 0; i < count; i++) |
1076 { | 1054 { |
1077 struct ipcp_lattice *lat = ipcp_get_lattice (info, i); | 1055 struct ipcp_lattice *lat = ipcp_get_lattice (info, i); |
1078 tree parm_tree = ipa_get_param (info, i); | |
1079 if (ipcp_lat_is_insertable (lat) | 1056 if (ipcp_lat_is_insertable (lat) |
1080 /* Do not count obviously unused arguments. */ | 1057 /* Do not count obviously unused arguments. */ |
1081 && (!is_gimple_reg (parm_tree) | 1058 && ipa_is_param_used (info, i)) |
1082 || gimple_default_def (DECL_STRUCT_FUNCTION (node->decl), | |
1083 parm_tree))) | |
1084 const_param++; | 1059 const_param++; |
1085 } | 1060 } |
1086 return const_param; | 1061 return const_param; |
1087 } | 1062 } |
1088 | 1063 |
1182 { | 1157 { |
1183 struct ipcp_lattice *lat = ipcp_get_lattice (info, i); | 1158 struct ipcp_lattice *lat = ipcp_get_lattice (info, i); |
1184 parm_tree = ipa_get_param (info, i); | 1159 parm_tree = ipa_get_param (info, i); |
1185 | 1160 |
1186 /* We can proactively remove obviously unused arguments. */ | 1161 /* We can proactively remove obviously unused arguments. */ |
1187 if (is_gimple_reg (parm_tree) | 1162 if (!ipa_is_param_used (info, i)) |
1188 && !gimple_default_def (DECL_STRUCT_FUNCTION (node->decl), | |
1189 parm_tree)) | |
1190 { | 1163 { |
1191 bitmap_set_bit (args_to_skip, i); | 1164 bitmap_set_bit (args_to_skip, i); |
1192 continue; | 1165 continue; |
1193 } | 1166 } |
1194 | 1167 |
1274 { | 1247 { |
1275 fprintf (dump_file, "\nProfiling info after insert stage:\n"); | 1248 fprintf (dump_file, "\nProfiling info after insert stage:\n"); |
1276 ipcp_print_profile_data (dump_file); | 1249 ipcp_print_profile_data (dump_file); |
1277 } | 1250 } |
1278 /* Free all IPCP structures. */ | 1251 /* Free all IPCP structures. */ |
1279 free_all_ipa_structures_after_ipa_cp (); | 1252 ipa_free_all_structures_after_ipa_cp (); |
1280 if (dump_file) | 1253 if (dump_file) |
1281 fprintf (dump_file, "\nIPA constant propagation end\n"); | 1254 fprintf (dump_file, "\nIPA constant propagation end\n"); |
1282 return 0; | 1255 return 0; |
1283 } | 1256 } |
1284 | 1257 |
1296 ipcp_init_stage (); | 1269 ipcp_init_stage (); |
1297 } | 1270 } |
1298 | 1271 |
1299 /* Write ipcp summary for nodes in SET. */ | 1272 /* Write ipcp summary for nodes in SET. */ |
1300 static void | 1273 static void |
1301 ipcp_write_summary (cgraph_node_set set) | 1274 ipcp_write_summary (cgraph_node_set set, |
1275 varpool_node_set vset ATTRIBUTE_UNUSED) | |
1302 { | 1276 { |
1303 ipa_prop_write_jump_functions (set); | 1277 ipa_prop_write_jump_functions (set); |
1304 } | 1278 } |
1305 | 1279 |
1306 /* Read ipcp summary. */ | 1280 /* Read ipcp summary. */ |
1331 0, /* properties_required */ | 1305 0, /* properties_required */ |
1332 0, /* properties_provided */ | 1306 0, /* properties_provided */ |
1333 0, /* properties_destroyed */ | 1307 0, /* properties_destroyed */ |
1334 0, /* todo_flags_start */ | 1308 0, /* todo_flags_start */ |
1335 TODO_dump_cgraph | TODO_dump_func | | 1309 TODO_dump_cgraph | TODO_dump_func | |
1336 TODO_remove_functions /* todo_flags_finish */ | 1310 TODO_remove_functions | TODO_ggc_collect /* todo_flags_finish */ |
1337 }, | 1311 }, |
1338 ipcp_generate_summary, /* generate_summary */ | 1312 ipcp_generate_summary, /* generate_summary */ |
1339 ipcp_write_summary, /* write_summary */ | 1313 ipcp_write_summary, /* write_summary */ |
1340 ipcp_read_summary, /* read_summary */ | 1314 ipcp_read_summary, /* read_summary */ |
1341 NULL, /* function_read_summary */ | 1315 NULL, /* write_optimization_summary */ |
1342 lto_ipa_fixup_call_notes, /* stmt_fixup */ | 1316 NULL, /* read_optimization_summary */ |
1317 NULL, /* stmt_fixup */ | |
1343 0, /* TODOs */ | 1318 0, /* TODOs */ |
1344 NULL, /* function_transform */ | 1319 NULL, /* function_transform */ |
1345 NULL, /* variable_transform */ | 1320 NULL, /* variable_transform */ |
1346 }; | 1321 }; |