Mercurial > hg > CbC > CbC_gcc
comparison gcc/ipa-split.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
111:04ced10e8804 | 131:84e7813d76e9 |
---|---|
1 /* Function splitting pass | 1 /* Function splitting pass |
2 Copyright (C) 2010-2017 Free Software Foundation, Inc. | 2 Copyright (C) 2010-2018 Free Software Foundation, Inc. |
3 Contributed by Jan Hubicka <jh@suse.cz> | 3 Contributed by Jan Hubicka <jh@suse.cz> |
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 |
102 #include "tree-inline.h" | 102 #include "tree-inline.h" |
103 #include "params.h" | 103 #include "params.h" |
104 #include "gimple-pretty-print.h" | 104 #include "gimple-pretty-print.h" |
105 #include "ipa-fnsummary.h" | 105 #include "ipa-fnsummary.h" |
106 #include "cfgloop.h" | 106 #include "cfgloop.h" |
107 #include "tree-chkp.h" | |
108 | 107 |
109 /* Per basic block info. */ | 108 /* Per basic block info. */ |
110 | 109 |
111 struct split_bb_info | 110 struct split_bb_info |
112 { | 111 { |
113 unsigned int size; | 112 unsigned int size; |
114 unsigned int time; | 113 sreal time; |
115 }; | 114 }; |
116 | 115 |
117 static vec<split_bb_info> bb_info_vec; | 116 static vec<split_bb_info> bb_info_vec; |
118 | 117 |
119 /* Description of split point. */ | 118 /* Description of split point. */ |
120 | 119 |
121 struct split_point | 120 struct split_point |
122 { | 121 { |
123 /* Size of the partitions. */ | 122 /* Size of the partitions. */ |
124 unsigned int header_time, header_size, split_time, split_size; | 123 sreal header_time, split_time; |
124 unsigned int header_size, split_size; | |
125 | 125 |
126 /* SSA names that need to be passed into spit function. */ | 126 /* SSA names that need to be passed into spit function. */ |
127 bitmap ssa_names_to_pass; | 127 bitmap ssa_names_to_pass; |
128 | 128 |
129 /* Basic block where we split (that will become entry point of new function. */ | 129 /* Basic block where we split (that will become entry point of new function. */ |
130 basic_block entry_bb; | 130 basic_block entry_bb; |
131 | |
132 /* Count for entering the split part. | |
133 This is not count of the entry_bb because it may be in loop. */ | |
134 profile_count count; | |
131 | 135 |
132 /* Basic blocks we are splitting away. */ | 136 /* Basic blocks we are splitting away. */ |
133 bitmap split_bbs; | 137 bitmap split_bbs; |
134 | 138 |
135 /* True when return value is computed on split part and thus it needs | 139 /* True when return value is computed on split part and thus it needs |
144 /* Set of basic blocks that are not allowed to dominate a split point. */ | 148 /* Set of basic blocks that are not allowed to dominate a split point. */ |
145 | 149 |
146 static bitmap forbidden_dominators; | 150 static bitmap forbidden_dominators; |
147 | 151 |
148 static tree find_retval (basic_block return_bb); | 152 static tree find_retval (basic_block return_bb); |
149 static tree find_retbnd (basic_block return_bb); | |
150 | 153 |
151 /* Callback for walk_stmt_load_store_addr_ops. If T is non-SSA automatic | 154 /* Callback for walk_stmt_load_store_addr_ops. If T is non-SSA automatic |
152 variable, check it if it is present in bitmap passed via DATA. */ | 155 variable, check it if it is present in bitmap passed via DATA. */ |
153 | 156 |
154 static bool | 157 static bool |
189 static void | 192 static void |
190 dump_split_point (FILE * file, struct split_point *current) | 193 dump_split_point (FILE * file, struct split_point *current) |
191 { | 194 { |
192 fprintf (file, | 195 fprintf (file, |
193 "Split point at BB %i\n" | 196 "Split point at BB %i\n" |
194 " header time: %i header size: %i\n" | 197 " header time: %f header size: %i\n" |
195 " split time: %i split size: %i\n bbs: ", | 198 " split time: %f split size: %i\n bbs: ", |
196 current->entry_bb->index, current->header_time, | 199 current->entry_bb->index, current->header_time.to_double (), |
197 current->header_size, current->split_time, current->split_size); | 200 current->header_size, current->split_time.to_double (), |
201 current->split_size); | |
198 dump_bitmap (file, current->split_bbs); | 202 dump_bitmap (file, current->split_bbs); |
199 fprintf (file, " SSA names to pass: "); | 203 fprintf (file, " SSA names to pass: "); |
200 dump_bitmap (file, current->ssa_names_to_pass); | 204 dump_bitmap (file, current->ssa_names_to_pass); |
201 } | 205 } |
202 | 206 |
424 unsigned int call_overhead; | 428 unsigned int call_overhead; |
425 edge e; | 429 edge e; |
426 edge_iterator ei; | 430 edge_iterator ei; |
427 gphi_iterator bsi; | 431 gphi_iterator bsi; |
428 unsigned int i; | 432 unsigned int i; |
429 int incoming_freq = 0; | |
430 tree retval; | 433 tree retval; |
431 tree retbnd; | |
432 bool back_edge = false; | 434 bool back_edge = false; |
433 | 435 |
434 if (dump_file && (dump_flags & TDF_DETAILS)) | 436 if (dump_file && (dump_flags & TDF_DETAILS)) |
435 dump_split_point (dump_file, current); | 437 dump_split_point (dump_file, current); |
436 | 438 |
439 current->count = profile_count::zero (); | |
437 FOR_EACH_EDGE (e, ei, current->entry_bb->preds) | 440 FOR_EACH_EDGE (e, ei, current->entry_bb->preds) |
438 { | 441 { |
439 if (e->flags & EDGE_DFS_BACK) | 442 if (e->flags & EDGE_DFS_BACK) |
440 back_edge = true; | 443 back_edge = true; |
441 if (!bitmap_bit_p (current->split_bbs, e->src->index)) | 444 if (!bitmap_bit_p (current->split_bbs, e->src->index)) |
442 incoming_freq += EDGE_FREQUENCY (e); | 445 current->count += e->count (); |
443 } | 446 } |
444 | 447 |
445 /* Do not split when we would end up calling function anyway. */ | 448 /* Do not split when we would end up calling function anyway. |
446 if (incoming_freq | 449 Compares are three state, use !(...<...) to also give up when outcome |
447 >= (ENTRY_BLOCK_PTR_FOR_FN (cfun)->frequency | 450 is unknown. */ |
448 * PARAM_VALUE (PARAM_PARTIAL_INLINING_ENTRY_PROBABILITY) / 100)) | 451 if (!(current->count |
452 < (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.apply_scale | |
453 (PARAM_VALUE (PARAM_PARTIAL_INLINING_ENTRY_PROBABILITY), 100)))) | |
449 { | 454 { |
450 /* When profile is guessed, we can not expect it to give us | 455 /* When profile is guessed, we can not expect it to give us |
451 realistic estimate on likelyness of function taking the | 456 realistic estimate on likelyness of function taking the |
452 complex path. As a special case, when tail of the function is | 457 complex path. As a special case, when tail of the function is |
453 a loop, enable splitting since inlining code skipping the loop | 458 a loop, enable splitting since inlining code skipping the loop |
454 is likely noticeable win. */ | 459 is likely noticeable win. */ |
455 if (back_edge | 460 if (back_edge |
456 && profile_status_for_fn (cfun) != PROFILE_READ | 461 && profile_status_for_fn (cfun) != PROFILE_READ |
457 && incoming_freq < ENTRY_BLOCK_PTR_FOR_FN (cfun)->frequency) | 462 && current->count |
463 < ENTRY_BLOCK_PTR_FOR_FN (cfun)->count) | |
458 { | 464 { |
459 if (dump_file && (dump_flags & TDF_DETAILS)) | 465 if (dump_file && (dump_flags & TDF_DETAILS)) |
460 fprintf (dump_file, | 466 { |
461 " Split before loop, accepting despite low frequencies %i %i.\n", | 467 fprintf (dump_file, |
462 incoming_freq, | 468 " Split before loop, accepting despite low counts"); |
463 ENTRY_BLOCK_PTR_FOR_FN (cfun)->frequency); | 469 current->count.dump (dump_file); |
470 fprintf (dump_file, " "); | |
471 ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.dump (dump_file); | |
472 } | |
464 } | 473 } |
465 else | 474 else |
466 { | 475 { |
467 if (dump_file && (dump_flags & TDF_DETAILS)) | 476 if (dump_file && (dump_flags & TDF_DETAILS)) |
468 fprintf (dump_file, | 477 fprintf (dump_file, |
544 if (dump_file && (dump_flags & TDF_DETAILS)) | 553 if (dump_file && (dump_flags & TDF_DETAILS)) |
545 fprintf (dump_file, | 554 fprintf (dump_file, |
546 " Refused: split size is smaller than call overhead\n"); | 555 " Refused: split size is smaller than call overhead\n"); |
547 return; | 556 return; |
548 } | 557 } |
558 /* FIXME: The logic here is not very precise, because inliner does use | |
559 inline predicates to reduce function body size. We add 10 to anticipate | |
560 that. Next stage1 we should try to be more meaningful here. */ | |
549 if (current->header_size + call_overhead | 561 if (current->header_size + call_overhead |
550 >= (unsigned int)(DECL_DECLARED_INLINE_P (current_function_decl) | 562 >= (unsigned int)(DECL_DECLARED_INLINE_P (current_function_decl) |
551 ? MAX_INLINE_INSNS_SINGLE | 563 ? MAX_INLINE_INSNS_SINGLE |
552 : MAX_INLINE_INSNS_AUTO)) | 564 : MAX_INLINE_INSNS_AUTO) + 10) |
553 { | 565 { |
554 if (dump_file && (dump_flags & TDF_DETAILS)) | 566 if (dump_file && (dump_flags & TDF_DETAILS)) |
555 fprintf (dump_file, | 567 fprintf (dump_file, |
556 " Refused: header size is too large for inline candidate\n"); | 568 " Refused: header size is too large for inline candidate\n"); |
557 return; | 569 return; |
560 /* Splitting functions brings the target out of comdat group; this will | 572 /* Splitting functions brings the target out of comdat group; this will |
561 lead to code duplication if the function is reused by other unit. | 573 lead to code duplication if the function is reused by other unit. |
562 Limit this duplication. This is consistent with limit in tree-sra.c | 574 Limit this duplication. This is consistent with limit in tree-sra.c |
563 FIXME: with LTO we ought to be able to do better! */ | 575 FIXME: with LTO we ought to be able to do better! */ |
564 if (DECL_ONE_ONLY (current_function_decl) | 576 if (DECL_ONE_ONLY (current_function_decl) |
565 && current->split_size >= (unsigned int) MAX_INLINE_INSNS_AUTO) | 577 && current->split_size >= (unsigned int) MAX_INLINE_INSNS_AUTO + 10) |
566 { | 578 { |
567 if (dump_file && (dump_flags & TDF_DETAILS)) | 579 if (dump_file && (dump_flags & TDF_DETAILS)) |
568 fprintf (dump_file, | 580 fprintf (dump_file, |
569 " Refused: function is COMDAT and tail is too large\n"); | 581 " Refused: function is COMDAT and tail is too large\n"); |
570 return; | 582 return; |
661 current->split_part_set_retval | 673 current->split_part_set_retval |
662 = bitmap_bit_p (non_ssa_vars, DECL_UID (retval)); | 674 = bitmap_bit_p (non_ssa_vars, DECL_UID (retval)); |
663 else | 675 else |
664 current->split_part_set_retval = true; | 676 current->split_part_set_retval = true; |
665 | 677 |
666 /* See if retbnd used by return bb is computed by header or split part. */ | |
667 retbnd = find_retbnd (return_bb); | |
668 if (retbnd) | |
669 { | |
670 bool split_part_set_retbnd | |
671 = split_part_set_ssa_name_p (retbnd, current, return_bb); | |
672 | |
673 /* If we have both return value and bounds then keep their definitions | |
674 in a single function. We use SSA names to link returned bounds and | |
675 value and therefore do not handle cases when result is passed by | |
676 reference (which should not be our case anyway since bounds are | |
677 returned for pointers only). */ | |
678 if ((DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)) | |
679 && current->split_part_set_retval) | |
680 || split_part_set_retbnd != current->split_part_set_retval) | |
681 { | |
682 if (dump_file && (dump_flags & TDF_DETAILS)) | |
683 fprintf (dump_file, | |
684 " Refused: split point splits return value and bounds\n"); | |
685 return; | |
686 } | |
687 } | |
688 | |
689 /* split_function fixes up at most one PHI non-virtual PHI node in return_bb, | 678 /* split_function fixes up at most one PHI non-virtual PHI node in return_bb, |
690 for the return value. If there are other PHIs, give up. */ | 679 for the return value. If there are other PHIs, give up. */ |
691 if (return_bb != EXIT_BLOCK_PTR_FOR_FN (cfun)) | 680 if (return_bb != EXIT_BLOCK_PTR_FOR_FN (cfun)) |
692 { | 681 { |
693 gphi_iterator psi; | 682 gphi_iterator psi; |
708 } | 697 } |
709 | 698 |
710 if (dump_file && (dump_flags & TDF_DETAILS)) | 699 if (dump_file && (dump_flags & TDF_DETAILS)) |
711 fprintf (dump_file, " Accepted!\n"); | 700 fprintf (dump_file, " Accepted!\n"); |
712 | 701 |
713 /* At the moment chose split point with lowest frequency and that leaves | 702 /* At the moment chose split point with lowest count and that leaves |
714 out smallest size of header. | 703 out smallest size of header. |
715 In future we might re-consider this heuristics. */ | 704 In future we might re-consider this heuristics. */ |
716 if (!best_split_point.split_bbs | 705 if (!best_split_point.split_bbs |
717 || best_split_point.entry_bb->frequency > current->entry_bb->frequency | 706 || best_split_point.count |
718 || (best_split_point.entry_bb->frequency == current->entry_bb->frequency | 707 > current->count |
708 || (best_split_point.count == current->count | |
719 && best_split_point.split_size < current->split_size)) | 709 && best_split_point.split_size < current->split_size)) |
720 | 710 |
721 { | 711 { |
722 if (dump_file && (dump_flags & TDF_DETAILS)) | 712 if (dump_file && (dump_flags & TDF_DETAILS)) |
723 fprintf (dump_file, " New best split point!\n"); | 713 fprintf (dump_file, " New best split point!\n"); |
812 && !gimple_clobber_p (gsi_stmt (bsi))) | 802 && !gimple_clobber_p (gsi_stmt (bsi))) |
813 return gimple_assign_rhs1 (gsi_stmt (bsi)); | 803 return gimple_assign_rhs1 (gsi_stmt (bsi)); |
814 return NULL; | 804 return NULL; |
815 } | 805 } |
816 | 806 |
817 /* Given return basic block RETURN_BB, see where return bounds are really | |
818 stored. */ | |
819 static tree | |
820 find_retbnd (basic_block return_bb) | |
821 { | |
822 gimple_stmt_iterator bsi; | |
823 for (bsi = gsi_last_bb (return_bb); !gsi_end_p (bsi); gsi_prev (&bsi)) | |
824 if (gimple_code (gsi_stmt (bsi)) == GIMPLE_RETURN) | |
825 return gimple_return_retbnd (gsi_stmt (bsi)); | |
826 return NULL; | |
827 } | |
828 | |
829 /* Callback for walk_stmt_load_store_addr_ops. If T is non-SSA automatic | 807 /* Callback for walk_stmt_load_store_addr_ops. If T is non-SSA automatic |
830 variable, mark it as used in bitmap passed via DATA. | 808 variable, mark it as used in bitmap passed via DATA. |
831 Return true when access to T prevents splitting the function. */ | 809 Return true when access to T prevents splitting the function. */ |
832 | 810 |
833 static bool | 811 static bool |
919 } | 897 } |
920 | 898 |
921 /* Check builtins that prevent splitting. */ | 899 /* Check builtins that prevent splitting. */ |
922 if (gimple_code (stmt) == GIMPLE_CALL | 900 if (gimple_code (stmt) == GIMPLE_CALL |
923 && (decl = gimple_call_fndecl (stmt)) != NULL_TREE | 901 && (decl = gimple_call_fndecl (stmt)) != NULL_TREE |
924 && DECL_BUILT_IN (decl) | 902 && fndecl_built_in_p (decl, BUILT_IN_NORMAL)) |
925 && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL) | |
926 switch (DECL_FUNCTION_CODE (decl)) | 903 switch (DECL_FUNCTION_CODE (decl)) |
927 { | 904 { |
928 /* FIXME: once we will allow passing non-parm values to split part, | 905 /* FIXME: once we will allow passing non-parm values to split part, |
929 we need to be sure to handle correct builtin_stack_save and | 906 we need to be sure to handle correct builtin_stack_save and |
930 builtin_stack_restore. At the moment we are safe; there is no | 907 builtin_stack_restore. At the moment we are safe; there is no |
1021 /* Stack entry index of earliest BB reachable from current BB | 998 /* Stack entry index of earliest BB reachable from current BB |
1022 or any BB visited later in DFS walk. */ | 999 or any BB visited later in DFS walk. */ |
1023 int earliest; | 1000 int earliest; |
1024 | 1001 |
1025 /* Overall time and size of all BBs reached from this BB in DFS walk. */ | 1002 /* Overall time and size of all BBs reached from this BB in DFS walk. */ |
1026 int overall_time, overall_size; | 1003 sreal overall_time; |
1004 int overall_size; | |
1027 | 1005 |
1028 /* When false we can not split on this BB. */ | 1006 /* When false we can not split on this BB. */ |
1029 bool can_split; | 1007 bool can_split; |
1030 }; | 1008 }; |
1031 | 1009 |
1046 The algorithm finds articulation after visiting the whole component | 1024 The algorithm finds articulation after visiting the whole component |
1047 reachable by it. This makes it convenient to collect information about | 1025 reachable by it. This makes it convenient to collect information about |
1048 the component used by consider_split. */ | 1026 the component used by consider_split. */ |
1049 | 1027 |
1050 static void | 1028 static void |
1051 find_split_points (basic_block return_bb, int overall_time, int overall_size) | 1029 find_split_points (basic_block return_bb, sreal overall_time, int overall_size) |
1052 { | 1030 { |
1053 stack_entry first; | 1031 stack_entry first; |
1054 vec<stack_entry> stack = vNULL; | 1032 vec<stack_entry> stack = vNULL; |
1055 basic_block bb; | 1033 basic_block bb; |
1056 struct split_point current; | 1034 struct split_point current; |
1209 cgraph_node *node, *cur_node = cgraph_node::get (current_function_decl); | 1187 cgraph_node *node, *cur_node = cgraph_node::get (current_function_decl); |
1210 basic_block call_bb; | 1188 basic_block call_bb; |
1211 gcall *call, *tsan_func_exit_call = NULL; | 1189 gcall *call, *tsan_func_exit_call = NULL; |
1212 edge e; | 1190 edge e; |
1213 edge_iterator ei; | 1191 edge_iterator ei; |
1214 tree retval = NULL, real_retval = NULL, retbnd = NULL; | 1192 tree retval = NULL, real_retval = NULL; |
1215 bool with_bounds = chkp_function_instrumented_p (current_function_decl); | |
1216 gimple *last_stmt = NULL; | 1193 gimple *last_stmt = NULL; |
1217 unsigned int i; | 1194 unsigned int i; |
1218 tree arg, ddef; | 1195 tree arg, ddef; |
1219 | 1196 |
1220 if (dump_file) | 1197 if (dump_file) |
1283 { | 1260 { |
1284 redirected = false; | 1261 redirected = false; |
1285 FOR_EACH_EDGE (e, ei, return_bb->preds) | 1262 FOR_EACH_EDGE (e, ei, return_bb->preds) |
1286 if (bitmap_bit_p (split_point->split_bbs, e->src->index)) | 1263 if (bitmap_bit_p (split_point->split_bbs, e->src->index)) |
1287 { | 1264 { |
1288 new_return_bb->frequency += EDGE_FREQUENCY (e); | 1265 new_return_bb->count += e->count (); |
1289 redirect_edge_and_branch (e, new_return_bb); | 1266 redirect_edge_and_branch (e, new_return_bb); |
1290 redirected = true; | 1267 redirected = true; |
1291 break; | 1268 break; |
1292 } | 1269 } |
1293 } | 1270 } |
1294 e = make_single_succ_edge (new_return_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0); | 1271 e = make_single_succ_edge (new_return_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0); |
1295 add_bb_to_loop (new_return_bb, current_loops->tree_root); | 1272 add_bb_to_loop (new_return_bb, current_loops->tree_root); |
1296 bitmap_set_bit (split_point->split_bbs, new_return_bb->index); | 1273 bitmap_set_bit (split_point->split_bbs, new_return_bb->index); |
1297 retbnd = find_retbnd (return_bb); | |
1298 } | 1274 } |
1299 /* When we pass around the value, use existing return block. */ | 1275 /* When we pass around the value, use existing return block. */ |
1300 else | 1276 else |
1301 { | 1277 bitmap_set_bit (split_point->split_bbs, return_bb->index); |
1302 bitmap_set_bit (split_point->split_bbs, return_bb->index); | |
1303 retbnd = find_retbnd (return_bb); | |
1304 } | |
1305 | 1278 |
1306 /* If RETURN_BB has virtual operand PHIs, they must be removed and the | 1279 /* If RETURN_BB has virtual operand PHIs, they must be removed and the |
1307 virtual operand marked for renaming as we change the CFG in a way that | 1280 virtual operand marked for renaming as we change the CFG in a way that |
1308 tree-inline is not able to compensate for. | 1281 tree-inline is not able to compensate for. |
1309 | 1282 |
1371 node->tp_first_run = cur_node->tp_first_run + 1; | 1344 node->tp_first_run = cur_node->tp_first_run + 1; |
1372 | 1345 |
1373 /* For usual cloning it is enough to clear builtin only when signature | 1346 /* For usual cloning it is enough to clear builtin only when signature |
1374 changes. For partial inlining we however can not expect the part | 1347 changes. For partial inlining we however can not expect the part |
1375 of builtin implementation to have same semantic as the whole. */ | 1348 of builtin implementation to have same semantic as the whole. */ |
1376 if (DECL_BUILT_IN (node->decl)) | 1349 if (fndecl_built_in_p (node->decl)) |
1377 { | 1350 { |
1378 DECL_BUILT_IN_CLASS (node->decl) = NOT_BUILT_IN; | 1351 DECL_BUILT_IN_CLASS (node->decl) = NOT_BUILT_IN; |
1379 DECL_FUNCTION_CODE (node->decl) = (enum built_in_function) 0; | 1352 DECL_FUNCTION_CODE (node->decl) = (enum built_in_function) 0; |
1380 } | 1353 } |
1381 | 1354 |
1415 else | 1388 else |
1416 gsi_next (&gsi); | 1389 gsi_next (&gsi); |
1417 } | 1390 } |
1418 } | 1391 } |
1419 | 1392 |
1420 /* If the original function is instrumented then it's | |
1421 part is also instrumented. */ | |
1422 if (with_bounds) | |
1423 chkp_function_mark_instrumented (node->decl); | |
1424 | |
1425 /* If the original function is declared inline, there is no point in issuing | 1393 /* If the original function is declared inline, there is no point in issuing |
1426 a warning for the non-inlinable part. */ | 1394 a warning for the non-inlinable part. */ |
1427 DECL_NO_INLINE_WARNING_P (node->decl) = 1; | 1395 DECL_NO_INLINE_WARNING_P (node->decl) = 1; |
1428 cur_node->remove_callees (); | 1396 cur_node->remove_callees (); |
1429 cur_node->remove_all_references (); | 1397 cur_node->remove_all_references (); |
1441 last_stmt = gsi_stmt (gsi); | 1409 last_stmt = gsi_stmt (gsi); |
1442 gsi_next (&gsi); | 1410 gsi_next (&gsi); |
1443 } | 1411 } |
1444 else | 1412 else |
1445 break; | 1413 break; |
1414 call_bb->count = split_point->count; | |
1446 e = split_block (split_point->entry_bb, last_stmt); | 1415 e = split_block (split_point->entry_bb, last_stmt); |
1447 remove_edge (e); | 1416 remove_edge (e); |
1448 | 1417 |
1449 /* Produce the call statement. */ | 1418 /* Produce the call statement. */ |
1450 gimple_stmt_iterator gsi = gsi_last_bb (call_bb); | 1419 gimple_stmt_iterator gsi = gsi_last_bb (call_bb); |
1454 arg = force_gimple_operand_gsi (&gsi, arg, true, NULL_TREE, | 1423 arg = force_gimple_operand_gsi (&gsi, arg, true, NULL_TREE, |
1455 false, GSI_CONTINUE_LINKING); | 1424 false, GSI_CONTINUE_LINKING); |
1456 args_to_pass[i] = arg; | 1425 args_to_pass[i] = arg; |
1457 } | 1426 } |
1458 call = gimple_build_call_vec (node->decl, args_to_pass); | 1427 call = gimple_build_call_vec (node->decl, args_to_pass); |
1459 gimple_call_set_with_bounds (call, with_bounds); | |
1460 gimple_set_block (call, DECL_INITIAL (current_function_decl)); | 1428 gimple_set_block (call, DECL_INITIAL (current_function_decl)); |
1461 args_to_pass.release (); | 1429 args_to_pass.release (); |
1462 | 1430 |
1463 /* For optimized away parameters, add on the caller side | 1431 /* For optimized away parameters, add on the caller side |
1464 before the call | 1432 before the call |
1468 it would have value parm_Y(D). */ | 1436 it would have value parm_Y(D). */ |
1469 if (args_to_skip) | 1437 if (args_to_skip) |
1470 { | 1438 { |
1471 vec<tree, va_gc> **debug_args = NULL; | 1439 vec<tree, va_gc> **debug_args = NULL; |
1472 unsigned i = 0, len = 0; | 1440 unsigned i = 0, len = 0; |
1473 if (MAY_HAVE_DEBUG_STMTS) | 1441 if (MAY_HAVE_DEBUG_BIND_STMTS) |
1474 { | 1442 { |
1475 debug_args = decl_debug_args_lookup (node->decl); | 1443 debug_args = decl_debug_args_lookup (node->decl); |
1476 if (debug_args) | 1444 if (debug_args) |
1477 len = vec_safe_length (*debug_args); | 1445 len = vec_safe_length (*debug_args); |
1478 } | 1446 } |
1481 if (bitmap_bit_p (args_to_skip, num) && is_gimple_reg (parm)) | 1449 if (bitmap_bit_p (args_to_skip, num) && is_gimple_reg (parm)) |
1482 { | 1450 { |
1483 tree ddecl; | 1451 tree ddecl; |
1484 gimple *def_temp; | 1452 gimple *def_temp; |
1485 | 1453 |
1486 /* This needs to be done even without MAY_HAVE_DEBUG_STMTS, | 1454 /* This needs to be done even without |
1487 otherwise if it didn't exist before, we'd end up with | 1455 MAY_HAVE_DEBUG_BIND_STMTS, otherwise if it didn't exist |
1488 different SSA_NAME_VERSIONs between -g and -g0. */ | 1456 before, we'd end up with different SSA_NAME_VERSIONs |
1457 between -g and -g0. */ | |
1489 arg = get_or_create_ssa_default_def (cfun, parm); | 1458 arg = get_or_create_ssa_default_def (cfun, parm); |
1490 if (!MAY_HAVE_DEBUG_STMTS || debug_args == NULL) | 1459 if (!MAY_HAVE_DEBUG_BIND_STMTS || debug_args == NULL) |
1491 continue; | 1460 continue; |
1492 | 1461 |
1493 while (i < len && (**debug_args)[i] != DECL_ORIGIN (parm)) | 1462 while (i < len && (**debug_args)[i] != DECL_ORIGIN (parm)) |
1494 i += 2; | 1463 i += 2; |
1495 if (i >= len) | 1464 if (i >= len) |
1597 if (update) | 1566 if (update) |
1598 update_stmt (stmt); | 1567 update_stmt (stmt); |
1599 } | 1568 } |
1600 } | 1569 } |
1601 } | 1570 } |
1602 | |
1603 /* Replace retbnd with new one. */ | |
1604 if (retbnd) | |
1605 { | |
1606 gimple_stmt_iterator bsi; | |
1607 for (bsi = gsi_last_bb (return_bb); !gsi_end_p (bsi); | |
1608 gsi_prev (&bsi)) | |
1609 if (gimple_code (gsi_stmt (bsi)) == GIMPLE_RETURN) | |
1610 { | |
1611 retbnd = copy_ssa_name (retbnd, call); | |
1612 gimple_return_set_retbnd (gsi_stmt (bsi), retbnd); | |
1613 update_stmt (gsi_stmt (bsi)); | |
1614 break; | |
1615 } | |
1616 } | |
1617 } | 1571 } |
1618 if (DECL_BY_REFERENCE (DECL_RESULT (current_function_decl))) | 1572 if (DECL_BY_REFERENCE (DECL_RESULT (current_function_decl))) |
1619 { | 1573 { |
1620 gimple_call_set_lhs (call, build_simple_mem_ref (retval)); | 1574 gimple_call_set_lhs (call, build_simple_mem_ref (retval)); |
1621 gsi_insert_after (&gsi, call, GSI_NEW_STMT); | 1575 gsi_insert_after (&gsi, call, GSI_NEW_STMT); |
1632 tem = make_ssa_name (tem, call); | 1586 tem = make_ssa_name (tem, call); |
1633 cpy = gimple_build_assign (retval, NOP_EXPR, tem); | 1587 cpy = gimple_build_assign (retval, NOP_EXPR, tem); |
1634 gsi_insert_after (&gsi, cpy, GSI_NEW_STMT); | 1588 gsi_insert_after (&gsi, cpy, GSI_NEW_STMT); |
1635 retval = tem; | 1589 retval = tem; |
1636 } | 1590 } |
1637 /* Build bndret call to obtain returned bounds. */ | |
1638 if (retbnd) | |
1639 chkp_insert_retbnd_call (retbnd, retval, &gsi); | |
1640 gimple_call_set_lhs (call, retval); | 1591 gimple_call_set_lhs (call, retval); |
1641 update_stmt (call); | 1592 update_stmt (call); |
1642 } | 1593 } |
1643 } | 1594 } |
1644 else | 1595 else |
1654 greturn *ret; | 1605 greturn *ret; |
1655 if (split_point->split_part_set_retval | 1606 if (split_point->split_part_set_retval |
1656 && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))) | 1607 && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))) |
1657 { | 1608 { |
1658 retval = DECL_RESULT (current_function_decl); | 1609 retval = DECL_RESULT (current_function_decl); |
1659 | |
1660 if (chkp_function_instrumented_p (current_function_decl) | |
1661 && BOUNDED_P (retval)) | |
1662 retbnd = create_tmp_reg (pointer_bounds_type_node); | |
1663 | 1610 |
1664 /* We use temporary register to hold value when aggregate_value_p | 1611 /* We use temporary register to hold value when aggregate_value_p |
1665 is false. Similarly for DECL_BY_REFERENCE we must avoid extra | 1612 is false. Similarly for DECL_BY_REFERENCE we must avoid extra |
1666 copy. */ | 1613 copy. */ |
1667 if (!aggregate_value_p (retval, TREE_TYPE (current_function_decl)) | 1614 if (!aggregate_value_p (retval, TREE_TYPE (current_function_decl)) |
1696 retval); | 1643 retval); |
1697 retval = gimple_assign_lhs (g); | 1644 retval = gimple_assign_lhs (g); |
1698 gsi_insert_after (&gsi, g, GSI_NEW_STMT); | 1645 gsi_insert_after (&gsi, g, GSI_NEW_STMT); |
1699 } | 1646 } |
1700 } | 1647 } |
1701 /* Build bndret call to obtain returned bounds. */ | |
1702 if (retbnd) | |
1703 chkp_insert_retbnd_call (retbnd, retval, &gsi); | |
1704 if (tsan_func_exit_call) | 1648 if (tsan_func_exit_call) |
1705 gsi_insert_after (&gsi, tsan_func_exit_call, GSI_NEW_STMT); | 1649 gsi_insert_after (&gsi, tsan_func_exit_call, GSI_NEW_STMT); |
1706 ret = gimple_build_return (retval); | 1650 ret = gimple_build_return (retval); |
1707 gsi_insert_after (&gsi, ret, GSI_NEW_STMT); | 1651 gsi_insert_after (&gsi, ret, GSI_NEW_STMT); |
1708 } | 1652 } |
1717 static unsigned int | 1661 static unsigned int |
1718 execute_split_functions (void) | 1662 execute_split_functions (void) |
1719 { | 1663 { |
1720 gimple_stmt_iterator bsi; | 1664 gimple_stmt_iterator bsi; |
1721 basic_block bb; | 1665 basic_block bb; |
1722 int overall_time = 0, overall_size = 0; | 1666 sreal overall_time = 0; |
1667 int overall_size = 0; | |
1723 int todo = 0; | 1668 int todo = 0; |
1724 struct cgraph_node *node = cgraph_node::get (current_function_decl); | 1669 struct cgraph_node *node = cgraph_node::get (current_function_decl); |
1725 | 1670 |
1726 if (flags_from_decl_or_type (current_function_decl) | 1671 if (flags_from_decl_or_type (current_function_decl) |
1727 & (ECF_NORETURN|ECF_MALLOC)) | 1672 & (ECF_NORETURN|ECF_MALLOC)) |
1734 { | 1679 { |
1735 if (dump_file) | 1680 if (dump_file) |
1736 fprintf (dump_file, "Not splitting: main function.\n"); | 1681 fprintf (dump_file, "Not splitting: main function.\n"); |
1737 return 0; | 1682 return 0; |
1738 } | 1683 } |
1684 if (node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED) | |
1685 { | |
1686 if (dump_file) | |
1687 fprintf (dump_file, "Not splitting: function is unlikely executed.\n"); | |
1688 return 0; | |
1689 } | |
1739 /* This can be relaxed; function might become inlinable after splitting | 1690 /* This can be relaxed; function might become inlinable after splitting |
1740 away the uninlinable part. */ | 1691 away the uninlinable part. */ |
1741 if (ipa_fn_summaries | 1692 if (ipa_fn_summaries |
1693 && ipa_fn_summaries->get (node) | |
1742 && !ipa_fn_summaries->get (node)->inlinable) | 1694 && !ipa_fn_summaries->get (node)->inlinable) |
1743 { | 1695 { |
1744 if (dump_file) | 1696 if (dump_file) |
1745 fprintf (dump_file, "Not splitting: not inlinable.\n"); | 1697 fprintf (dump_file, "Not splitting: not inlinable.\n"); |
1746 return 0; | 1698 return 0; |
1808 forbidden_dominators = BITMAP_ALLOC (NULL); | 1760 forbidden_dominators = BITMAP_ALLOC (NULL); |
1809 calculate_dominance_info (CDI_DOMINATORS); | 1761 calculate_dominance_info (CDI_DOMINATORS); |
1810 | 1762 |
1811 /* Compute local info about basic blocks and determine function size/time. */ | 1763 /* Compute local info about basic blocks and determine function size/time. */ |
1812 bb_info_vec.safe_grow_cleared (last_basic_block_for_fn (cfun) + 1); | 1764 bb_info_vec.safe_grow_cleared (last_basic_block_for_fn (cfun) + 1); |
1813 memset (&best_split_point, 0, sizeof (best_split_point)); | 1765 best_split_point.split_bbs = NULL; |
1814 basic_block return_bb = find_return_bb (); | 1766 basic_block return_bb = find_return_bb (); |
1815 int tsan_exit_found = -1; | 1767 int tsan_exit_found = -1; |
1816 FOR_EACH_BB_FN (bb, cfun) | 1768 FOR_EACH_BB_FN (bb, cfun) |
1817 { | 1769 { |
1818 int time = 0; | 1770 sreal time = 0; |
1819 int size = 0; | 1771 int size = 0; |
1820 int freq = compute_call_stmt_bb_frequency (current_function_decl, bb); | 1772 sreal freq = bb->count.to_sreal_scale |
1773 (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count); | |
1821 | 1774 |
1822 if (dump_file && (dump_flags & TDF_DETAILS)) | 1775 if (dump_file && (dump_flags & TDF_DETAILS)) |
1823 fprintf (dump_file, "Basic block %i\n", bb->index); | 1776 fprintf (dump_file, "Basic block %i\n", bb->index); |
1824 | 1777 |
1825 for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) | 1778 for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) |
1826 { | 1779 { |
1827 int this_time, this_size; | 1780 sreal this_time; |
1781 int this_size; | |
1828 gimple *stmt = gsi_stmt (bsi); | 1782 gimple *stmt = gsi_stmt (bsi); |
1829 | 1783 |
1830 this_size = estimate_num_insns (stmt, &eni_size_weights); | 1784 this_size = estimate_num_insns (stmt, &eni_size_weights); |
1831 this_time = estimate_num_insns (stmt, &eni_time_weights) * freq; | 1785 this_time = (sreal)estimate_num_insns (stmt, &eni_time_weights) |
1786 * freq; | |
1832 size += this_size; | 1787 size += this_size; |
1833 time += this_time; | 1788 time += this_time; |
1834 check_forbidden_calls (stmt); | 1789 check_forbidden_calls (stmt); |
1835 | 1790 |
1836 if (dump_file && (dump_flags & TDF_DETAILS)) | 1791 if (dump_file && (dump_flags & TDF_DETAILS)) |
1837 { | 1792 { |
1838 fprintf (dump_file, " freq:%6i size:%3i time:%3i ", | 1793 fprintf (dump_file, " freq:%4.2f size:%3i time:%4.2f ", |
1839 freq, this_size, this_time); | 1794 freq.to_double (), this_size, this_time.to_double ()); |
1840 print_gimple_stmt (dump_file, stmt, 0); | 1795 print_gimple_stmt (dump_file, stmt, 0); |
1841 } | 1796 } |
1842 | 1797 |
1843 if ((flag_sanitize & SANITIZE_THREAD) | 1798 if ((flag_sanitize & SANITIZE_THREAD) |
1844 && gimple_call_internal_p (stmt, IFN_TSAN_FUNC_EXIT)) | 1799 && gimple_call_internal_p (stmt, IFN_TSAN_FUNC_EXIT)) |