Mercurial > hg > CbC > CbC_gcc
comparison gcc/tree-ssa-loop-im.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 /* Loop invariant motion. | 1 /* Loop invariant motion. |
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Free Software | 2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2010 |
3 Foundation, Inc. | 3 Free Software Foundation, Inc. |
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 | 7 GCC is free software; you can redistribute it and/or modify it |
8 under the terms of the GNU General Public License as published by the | 8 under the terms of the GNU General Public License as published by the |
21 #include "config.h" | 21 #include "config.h" |
22 #include "system.h" | 22 #include "system.h" |
23 #include "coretypes.h" | 23 #include "coretypes.h" |
24 #include "tm.h" | 24 #include "tm.h" |
25 #include "tree.h" | 25 #include "tree.h" |
26 #include "rtl.h" | |
27 #include "tm_p.h" | 26 #include "tm_p.h" |
28 #include "hard-reg-set.h" | |
29 #include "basic-block.h" | 27 #include "basic-block.h" |
30 #include "output.h" | 28 #include "output.h" |
31 #include "diagnostic.h" | 29 #include "diagnostic.h" |
30 #include "gimple-pretty-print.h" | |
31 #include "tree-pretty-print.h" | |
32 #include "tree-flow.h" | 32 #include "tree-flow.h" |
33 #include "tree-dump.h" | 33 #include "tree-dump.h" |
34 #include "timevar.h" | 34 #include "timevar.h" |
35 #include "cfgloop.h" | 35 #include "cfgloop.h" |
36 #include "domwalk.h" | 36 #include "domwalk.h" |
37 #include "params.h" | 37 #include "params.h" |
38 #include "tree-pass.h" | 38 #include "tree-pass.h" |
39 #include "flags.h" | 39 #include "flags.h" |
40 #include "real.h" | |
41 #include "hashtab.h" | 40 #include "hashtab.h" |
42 #include "tree-affine.h" | 41 #include "tree-affine.h" |
43 #include "pointer-set.h" | 42 #include "pointer-set.h" |
44 #include "tree-ssa-propagate.h" | 43 #include "tree-ssa-propagate.h" |
45 | 44 |
357 /* If we perform unswitching, force the operands of the invariant | 356 /* If we perform unswitching, force the operands of the invariant |
358 condition to be moved out of the loop. */ | 357 condition to be moved out of the loop. */ |
359 return MOVE_POSSIBLE; | 358 return MOVE_POSSIBLE; |
360 } | 359 } |
361 | 360 |
361 if (gimple_code (stmt) == GIMPLE_PHI | |
362 && gimple_phi_num_args (stmt) <= 2 | |
363 && is_gimple_reg (gimple_phi_result (stmt)) | |
364 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_phi_result (stmt))) | |
365 return MOVE_POSSIBLE; | |
366 | |
362 if (gimple_get_lhs (stmt) == NULL_TREE) | 367 if (gimple_get_lhs (stmt) == NULL_TREE) |
363 return MOVE_IMPOSSIBLE; | 368 return MOVE_IMPOSSIBLE; |
364 | 369 |
365 if (gimple_vdef (stmt)) | 370 if (gimple_vdef (stmt)) |
366 return MOVE_IMPOSSIBLE; | 371 return MOVE_IMPOSSIBLE; |
511 { | 516 { |
512 tree fndecl; | 517 tree fndecl; |
513 unsigned cost = 1; | 518 unsigned cost = 1; |
514 | 519 |
515 /* Always try to create possibilities for unswitching. */ | 520 /* Always try to create possibilities for unswitching. */ |
516 if (gimple_code (stmt) == GIMPLE_COND) | 521 if (gimple_code (stmt) == GIMPLE_COND |
522 || gimple_code (stmt) == GIMPLE_PHI) | |
517 return LIM_EXPENSIVE; | 523 return LIM_EXPENSIVE; |
518 | 524 |
519 /* Hoisting memory references out should almost surely be a win. */ | 525 /* Hoisting memory references out should almost surely be a win. */ |
520 if (gimple_references_memory_p (stmt)) | 526 if (gimple_references_memory_p (stmt)) |
521 cost += 20; | 527 cost += 20; |
649 | 655 |
650 gcc_assert (ref != NULL); | 656 gcc_assert (ref != NULL); |
651 return ref; | 657 return ref; |
652 } | 658 } |
653 | 659 |
660 /* From a controlling predicate in DOM determine the arguments from | |
661 the PHI node PHI that are chosen if the predicate evaluates to | |
662 true and false and store them to *TRUE_ARG_P and *FALSE_ARG_P if | |
663 they are non-NULL. Returns true if the arguments can be determined, | |
664 else return false. */ | |
665 | |
666 static bool | |
667 extract_true_false_args_from_phi (basic_block dom, gimple phi, | |
668 tree *true_arg_p, tree *false_arg_p) | |
669 { | |
670 basic_block bb = gimple_bb (phi); | |
671 edge true_edge, false_edge, tem; | |
672 tree arg0 = NULL_TREE, arg1 = NULL_TREE; | |
673 | |
674 /* We have to verify that one edge into the PHI node is dominated | |
675 by the true edge of the predicate block and the other edge | |
676 dominated by the false edge. This ensures that the PHI argument | |
677 we are going to take is completely determined by the path we | |
678 take from the predicate block. */ | |
679 extract_true_false_edges_from_block (dom, &true_edge, &false_edge); | |
680 tem = EDGE_PRED (bb, 0); | |
681 if (tem == true_edge | |
682 || tem->src == true_edge->dest | |
683 || dominated_by_p (CDI_DOMINATORS, | |
684 tem->src, true_edge->dest)) | |
685 arg0 = PHI_ARG_DEF (phi, tem->dest_idx); | |
686 else if (tem == false_edge | |
687 || tem->src == false_edge->dest | |
688 || dominated_by_p (CDI_DOMINATORS, | |
689 tem->src, false_edge->dest)) | |
690 arg1 = PHI_ARG_DEF (phi, tem->dest_idx); | |
691 else | |
692 return false; | |
693 tem = EDGE_PRED (bb, 1); | |
694 if (tem == true_edge | |
695 || tem->src == true_edge->dest | |
696 || dominated_by_p (CDI_DOMINATORS, | |
697 tem->src, true_edge->dest)) | |
698 arg0 = PHI_ARG_DEF (phi, tem->dest_idx); | |
699 else if (tem == false_edge | |
700 || tem->src == false_edge->dest | |
701 || dominated_by_p (CDI_DOMINATORS, | |
702 tem->src, false_edge->dest)) | |
703 arg1 = PHI_ARG_DEF (phi, tem->dest_idx); | |
704 else | |
705 return false; | |
706 if (!arg0 || !arg1) | |
707 return false; | |
708 | |
709 if (true_arg_p) | |
710 *true_arg_p = arg0; | |
711 if (false_arg_p) | |
712 *false_arg_p = arg1; | |
713 | |
714 return true; | |
715 } | |
716 | |
654 /* Determine the outermost loop to that it is possible to hoist a statement | 717 /* Determine the outermost loop to that it is possible to hoist a statement |
655 STMT and store it to LIM_DATA (STMT)->max_loop. To do this we determine | 718 STMT and store it to LIM_DATA (STMT)->max_loop. To do this we determine |
656 the outermost loop in that the value computed by STMT is invariant. | 719 the outermost loop in that the value computed by STMT is invariant. |
657 If MUST_PRESERVE_EXEC is true, additionally choose such a loop that | 720 If MUST_PRESERVE_EXEC is true, additionally choose such a loop that |
658 we preserve the fact whether STMT is executed. It also fills other related | 721 we preserve the fact whether STMT is executed. It also fills other related |
675 level = ALWAYS_EXECUTED_IN (bb); | 738 level = ALWAYS_EXECUTED_IN (bb); |
676 else | 739 else |
677 level = superloop_at_depth (loop, 1); | 740 level = superloop_at_depth (loop, 1); |
678 lim_data->max_loop = level; | 741 lim_data->max_loop = level; |
679 | 742 |
680 FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_USE) | 743 if (gimple_code (stmt) == GIMPLE_PHI) |
681 if (!add_dependency (val, lim_data, loop, true)) | 744 { |
682 return false; | 745 use_operand_p use_p; |
746 unsigned min_cost = UINT_MAX; | |
747 unsigned total_cost = 0; | |
748 struct lim_aux_data *def_data; | |
749 | |
750 /* We will end up promoting dependencies to be unconditionally | |
751 evaluated. For this reason the PHI cost (and thus the | |
752 cost we remove from the loop by doing the invariant motion) | |
753 is that of the cheapest PHI argument dependency chain. */ | |
754 FOR_EACH_PHI_ARG (use_p, stmt, iter, SSA_OP_USE) | |
755 { | |
756 val = USE_FROM_PTR (use_p); | |
757 if (TREE_CODE (val) != SSA_NAME) | |
758 continue; | |
759 if (!add_dependency (val, lim_data, loop, false)) | |
760 return false; | |
761 def_data = get_lim_data (SSA_NAME_DEF_STMT (val)); | |
762 if (def_data) | |
763 { | |
764 min_cost = MIN (min_cost, def_data->cost); | |
765 total_cost += def_data->cost; | |
766 } | |
767 } | |
768 | |
769 lim_data->cost += min_cost; | |
770 | |
771 if (gimple_phi_num_args (stmt) > 1) | |
772 { | |
773 basic_block dom = get_immediate_dominator (CDI_DOMINATORS, bb); | |
774 gimple cond; | |
775 if (gsi_end_p (gsi_last_bb (dom))) | |
776 return false; | |
777 cond = gsi_stmt (gsi_last_bb (dom)); | |
778 if (gimple_code (cond) != GIMPLE_COND) | |
779 return false; | |
780 /* Verify that this is an extended form of a diamond and | |
781 the PHI arguments are completely controlled by the | |
782 predicate in DOM. */ | |
783 if (!extract_true_false_args_from_phi (dom, stmt, NULL, NULL)) | |
784 return false; | |
785 | |
786 /* Fold in dependencies and cost of the condition. */ | |
787 FOR_EACH_SSA_TREE_OPERAND (val, cond, iter, SSA_OP_USE) | |
788 { | |
789 if (!add_dependency (val, lim_data, loop, false)) | |
790 return false; | |
791 def_data = get_lim_data (SSA_NAME_DEF_STMT (val)); | |
792 if (def_data) | |
793 total_cost += def_data->cost; | |
794 } | |
795 | |
796 /* We want to avoid unconditionally executing very expensive | |
797 operations. As costs for our dependencies cannot be | |
798 negative just claim we are not invariand for this case. | |
799 We also are not sure whether the control-flow inside the | |
800 loop will vanish. */ | |
801 if (total_cost - min_cost >= 2 * LIM_EXPENSIVE | |
802 && !(min_cost != 0 | |
803 && total_cost / min_cost <= 2)) | |
804 return false; | |
805 | |
806 /* Assume that the control-flow in the loop will vanish. | |
807 ??? We should verify this and not artificially increase | |
808 the cost if that is not the case. */ | |
809 lim_data->cost += stmt_cost (stmt); | |
810 } | |
811 | |
812 return true; | |
813 } | |
814 else | |
815 FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_USE) | |
816 if (!add_dependency (val, lim_data, loop, true)) | |
817 return false; | |
683 | 818 |
684 if (gimple_vuse (stmt)) | 819 if (gimple_vuse (stmt)) |
685 { | 820 { |
686 mem_ref_p ref = mem_ref_in_stmt (stmt); | 821 mem_ref_p ref = mem_ref_in_stmt (stmt); |
687 | 822 |
917 return; | 1052 return; |
918 | 1053 |
919 if (dump_file && (dump_flags & TDF_DETAILS)) | 1054 if (dump_file && (dump_flags & TDF_DETAILS)) |
920 fprintf (dump_file, "Basic block %d (loop %d -- depth %d):\n\n", | 1055 fprintf (dump_file, "Basic block %d (loop %d -- depth %d):\n\n", |
921 bb->index, bb->loop_father->num, loop_depth (bb->loop_father)); | 1056 bb->index, bb->loop_father->num, loop_depth (bb->loop_father)); |
1057 | |
1058 /* Look at PHI nodes, but only if there is at most two. | |
1059 ??? We could relax this further by post-processing the inserted | |
1060 code and transforming adjacent cond-exprs with the same predicate | |
1061 to control flow again. */ | |
1062 bsi = gsi_start_phis (bb); | |
1063 if (!gsi_end_p (bsi) | |
1064 && ((gsi_next (&bsi), gsi_end_p (bsi)) | |
1065 || (gsi_next (&bsi), gsi_end_p (bsi)))) | |
1066 for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi)) | |
1067 { | |
1068 stmt = gsi_stmt (bsi); | |
1069 | |
1070 pos = movement_possibility (stmt); | |
1071 if (pos == MOVE_IMPOSSIBLE) | |
1072 continue; | |
1073 | |
1074 lim_data = init_lim_data (stmt); | |
1075 lim_data->always_executed_in = outermost; | |
1076 | |
1077 if (!determine_max_movement (stmt, false)) | |
1078 { | |
1079 lim_data->max_loop = NULL; | |
1080 continue; | |
1081 } | |
1082 | |
1083 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1084 { | |
1085 print_gimple_stmt (dump_file, stmt, 2, 0); | |
1086 fprintf (dump_file, " invariant up to level %d, cost %d.\n\n", | |
1087 loop_depth (lim_data->max_loop), | |
1088 lim_data->cost); | |
1089 } | |
1090 | |
1091 if (lim_data->cost >= LIM_EXPENSIVE) | |
1092 set_profitable_level (stmt); | |
1093 } | |
922 | 1094 |
923 for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) | 1095 for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) |
924 { | 1096 { |
925 stmt = gsi_stmt (bsi); | 1097 stmt = gsi_stmt (bsi); |
926 | 1098 |
1019 /* Hoist the statements in basic block BB out of the loops prescribed by | 1191 /* Hoist the statements in basic block BB out of the loops prescribed by |
1020 data stored in LIM_DATA structures associated with each statement. Callback | 1192 data stored in LIM_DATA structures associated with each statement. Callback |
1021 for walk_dominator_tree. */ | 1193 for walk_dominator_tree. */ |
1022 | 1194 |
1023 static void | 1195 static void |
1024 move_computations_stmt (struct dom_walk_data *dw_data ATTRIBUTE_UNUSED, | 1196 move_computations_stmt (struct dom_walk_data *dw_data, |
1025 basic_block bb) | 1197 basic_block bb) |
1026 { | 1198 { |
1027 struct loop *level; | 1199 struct loop *level; |
1028 gimple_stmt_iterator bsi; | 1200 gimple_stmt_iterator bsi; |
1029 gimple stmt; | 1201 gimple stmt; |
1030 unsigned cost = 0; | 1202 unsigned cost = 0; |
1031 struct lim_aux_data *lim_data; | 1203 struct lim_aux_data *lim_data; |
1032 | 1204 |
1033 if (!loop_outer (bb->loop_father)) | 1205 if (!loop_outer (bb->loop_father)) |
1034 return; | 1206 return; |
1207 | |
1208 for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); ) | |
1209 { | |
1210 gimple new_stmt; | |
1211 stmt = gsi_stmt (bsi); | |
1212 | |
1213 lim_data = get_lim_data (stmt); | |
1214 if (lim_data == NULL) | |
1215 { | |
1216 gsi_next (&bsi); | |
1217 continue; | |
1218 } | |
1219 | |
1220 cost = lim_data->cost; | |
1221 level = lim_data->tgt_loop; | |
1222 clear_lim_data (stmt); | |
1223 | |
1224 if (!level) | |
1225 { | |
1226 gsi_next (&bsi); | |
1227 continue; | |
1228 } | |
1229 | |
1230 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1231 { | |
1232 fprintf (dump_file, "Moving PHI node\n"); | |
1233 print_gimple_stmt (dump_file, stmt, 0, 0); | |
1234 fprintf (dump_file, "(cost %u) out of loop %d.\n\n", | |
1235 cost, level->num); | |
1236 } | |
1237 | |
1238 if (gimple_phi_num_args (stmt) == 1) | |
1239 { | |
1240 tree arg = PHI_ARG_DEF (stmt, 0); | |
1241 new_stmt = gimple_build_assign_with_ops (TREE_CODE (arg), | |
1242 gimple_phi_result (stmt), | |
1243 arg, NULL_TREE); | |
1244 SSA_NAME_DEF_STMT (gimple_phi_result (stmt)) = new_stmt; | |
1245 } | |
1246 else | |
1247 { | |
1248 basic_block dom = get_immediate_dominator (CDI_DOMINATORS, bb); | |
1249 gimple cond = gsi_stmt (gsi_last_bb (dom)); | |
1250 tree arg0 = NULL_TREE, arg1 = NULL_TREE, t; | |
1251 /* Get the PHI arguments corresponding to the true and false | |
1252 edges of COND. */ | |
1253 extract_true_false_args_from_phi (dom, stmt, &arg0, &arg1); | |
1254 gcc_assert (arg0 && arg1); | |
1255 t = build2 (gimple_cond_code (cond), boolean_type_node, | |
1256 gimple_cond_lhs (cond), gimple_cond_rhs (cond)); | |
1257 t = build3 (COND_EXPR, TREE_TYPE (gimple_phi_result (stmt)), | |
1258 t, arg0, arg1); | |
1259 new_stmt = gimple_build_assign_with_ops (COND_EXPR, | |
1260 gimple_phi_result (stmt), | |
1261 t, NULL_TREE); | |
1262 SSA_NAME_DEF_STMT (gimple_phi_result (stmt)) = new_stmt; | |
1263 *((unsigned int *)(dw_data->global_data)) |= TODO_cleanup_cfg; | |
1264 } | |
1265 gsi_insert_on_edge (loop_preheader_edge (level), new_stmt); | |
1266 remove_phi_node (&bsi, false); | |
1267 } | |
1035 | 1268 |
1036 for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); ) | 1269 for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); ) |
1037 { | 1270 { |
1038 stmt = gsi_stmt (bsi); | 1271 stmt = gsi_stmt (bsi); |
1039 | 1272 |
1074 } | 1307 } |
1075 | 1308 |
1076 /* Hoist the statements out of the loops prescribed by data stored in | 1309 /* Hoist the statements out of the loops prescribed by data stored in |
1077 LIM_DATA structures associated with each statement.*/ | 1310 LIM_DATA structures associated with each statement.*/ |
1078 | 1311 |
1079 static void | 1312 static unsigned int |
1080 move_computations (void) | 1313 move_computations (void) |
1081 { | 1314 { |
1082 struct dom_walk_data walk_data; | 1315 struct dom_walk_data walk_data; |
1316 unsigned int todo = 0; | |
1083 | 1317 |
1084 memset (&walk_data, 0, sizeof (struct dom_walk_data)); | 1318 memset (&walk_data, 0, sizeof (struct dom_walk_data)); |
1319 walk_data.global_data = &todo; | |
1085 walk_data.dom_direction = CDI_DOMINATORS; | 1320 walk_data.dom_direction = CDI_DOMINATORS; |
1086 walk_data.before_dom_children = move_computations_stmt; | 1321 walk_data.before_dom_children = move_computations_stmt; |
1087 | 1322 |
1088 init_walk_dominator_tree (&walk_data); | 1323 init_walk_dominator_tree (&walk_data); |
1089 walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR); | 1324 walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR); |
1090 fini_walk_dominator_tree (&walk_data); | 1325 fini_walk_dominator_tree (&walk_data); |
1091 | 1326 |
1092 gsi_commit_edge_inserts (); | 1327 gsi_commit_edge_inserts (); |
1093 if (need_ssa_update_p (cfun)) | 1328 if (need_ssa_update_p (cfun)) |
1094 rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa); | 1329 rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa); |
1330 | |
1331 return todo; | |
1095 } | 1332 } |
1096 | 1333 |
1097 /* Checks whether the statement defining variable *INDEX can be hoisted | 1334 /* Checks whether the statement defining variable *INDEX can be hoisted |
1098 out of the loop passed in DATA. Callback for for_each_index. */ | 1335 out of the loop passed in DATA. Callback for for_each_index. */ |
1099 | 1336 |
1774 gen_lsm_tmp_name (TREE_OPERAND (ref, 0)); | 2011 gen_lsm_tmp_name (TREE_OPERAND (ref, 0)); |
1775 lsm_tmp_name_add ("_"); | 2012 lsm_tmp_name_add ("_"); |
1776 name = get_name (TREE_OPERAND (ref, 1)); | 2013 name = get_name (TREE_OPERAND (ref, 1)); |
1777 if (!name) | 2014 if (!name) |
1778 name = "F"; | 2015 name = "F"; |
1779 lsm_tmp_name_add ("_"); | |
1780 lsm_tmp_name_add (name); | 2016 lsm_tmp_name_add (name); |
2017 break; | |
1781 | 2018 |
1782 case ARRAY_REF: | 2019 case ARRAY_REF: |
1783 gen_lsm_tmp_name (TREE_OPERAND (ref, 0)); | 2020 gen_lsm_tmp_name (TREE_OPERAND (ref, 0)); |
1784 lsm_tmp_name_add ("_I"); | 2021 lsm_tmp_name_add ("_I"); |
1785 break; | 2022 break; |
1898 ref = VEC_index (mem_ref_p, memory_accesses.refs_list, i); | 2135 ref = VEC_index (mem_ref_p, memory_accesses.refs_list, i); |
1899 execute_sm (loop, exits, ref); | 2136 execute_sm (loop, exits, ref); |
1900 } | 2137 } |
1901 } | 2138 } |
1902 | 2139 |
1903 /* Returns true if REF is always accessed in LOOP. */ | 2140 /* Returns true if REF is always accessed in LOOP. If STORED_P is true |
2141 make sure REF is always stored to in LOOP. */ | |
1904 | 2142 |
1905 static bool | 2143 static bool |
1906 ref_always_accessed_p (struct loop *loop, mem_ref_p ref) | 2144 ref_always_accessed_p (struct loop *loop, mem_ref_p ref, bool stored_p) |
1907 { | 2145 { |
1908 VEC (mem_ref_loc_p, heap) *locs = NULL; | 2146 VEC (mem_ref_loc_p, heap) *locs = NULL; |
1909 unsigned i; | 2147 unsigned i; |
1910 mem_ref_loc_p loc; | 2148 mem_ref_loc_p loc; |
1911 bool ret = false; | 2149 bool ret = false; |
1912 struct loop *must_exec; | 2150 struct loop *must_exec; |
2151 tree base; | |
2152 | |
2153 base = get_base_address (ref->mem); | |
2154 if (INDIRECT_REF_P (base)) | |
2155 base = TREE_OPERAND (base, 0); | |
1913 | 2156 |
1914 get_all_locs_in_loop (loop, ref, &locs); | 2157 get_all_locs_in_loop (loop, ref, &locs); |
1915 for (i = 0; VEC_iterate (mem_ref_loc_p, locs, i, loc); i++) | 2158 for (i = 0; VEC_iterate (mem_ref_loc_p, locs, i, loc); i++) |
1916 { | 2159 { |
1917 if (!get_lim_data (loc->stmt)) | 2160 if (!get_lim_data (loc->stmt)) |
1918 continue; | 2161 continue; |
2162 | |
2163 /* If we require an always executed store make sure the statement | |
2164 stores to the reference. */ | |
2165 if (stored_p) | |
2166 { | |
2167 tree lhs; | |
2168 if (!gimple_get_lhs (loc->stmt)) | |
2169 continue; | |
2170 lhs = get_base_address (gimple_get_lhs (loc->stmt)); | |
2171 if (!lhs) | |
2172 continue; | |
2173 if (INDIRECT_REF_P (lhs)) | |
2174 lhs = TREE_OPERAND (lhs, 0); | |
2175 if (lhs != base) | |
2176 continue; | |
2177 } | |
1919 | 2178 |
1920 must_exec = get_lim_data (loc->stmt)->always_executed_in; | 2179 must_exec = get_lim_data (loc->stmt)->always_executed_in; |
1921 if (!must_exec) | 2180 if (!must_exec) |
1922 continue; | 2181 continue; |
1923 | 2182 |
2052 /* Returns true if we can perform store motion of REF from LOOP. */ | 2311 /* Returns true if we can perform store motion of REF from LOOP. */ |
2053 | 2312 |
2054 static bool | 2313 static bool |
2055 can_sm_ref_p (struct loop *loop, mem_ref_p ref) | 2314 can_sm_ref_p (struct loop *loop, mem_ref_p ref) |
2056 { | 2315 { |
2316 tree base; | |
2317 | |
2057 /* Unless the reference is stored in the loop, there is nothing to do. */ | 2318 /* Unless the reference is stored in the loop, there is nothing to do. */ |
2058 if (!bitmap_bit_p (ref->stored, loop->num)) | 2319 if (!bitmap_bit_p (ref->stored, loop->num)) |
2059 return false; | 2320 return false; |
2060 | 2321 |
2061 /* It should be movable. */ | 2322 /* It should be movable. */ |
2062 if (!is_gimple_reg_type (TREE_TYPE (ref->mem)) | 2323 if (!is_gimple_reg_type (TREE_TYPE (ref->mem)) |
2063 || TREE_THIS_VOLATILE (ref->mem) | 2324 || TREE_THIS_VOLATILE (ref->mem) |
2064 || !for_each_index (&ref->mem, may_move_till, loop)) | 2325 || !for_each_index (&ref->mem, may_move_till, loop)) |
2065 return false; | 2326 return false; |
2066 | 2327 |
2067 /* If it can trap, it must be always executed in LOOP. */ | 2328 /* If it can trap, it must be always executed in LOOP. |
2068 if (tree_could_trap_p (ref->mem) | 2329 Readonly memory locations may trap when storing to them, but |
2069 && !ref_always_accessed_p (loop, ref)) | 2330 tree_could_trap_p is a predicate for rvalues, so check that |
2331 explicitly. */ | |
2332 base = get_base_address (ref->mem); | |
2333 if ((tree_could_trap_p (ref->mem) | |
2334 || (DECL_P (base) && TREE_READONLY (base))) | |
2335 && !ref_always_accessed_p (loop, ref, true)) | |
2070 return false; | 2336 return false; |
2071 | 2337 |
2072 /* And it must be independent on all other memory references | 2338 /* And it must be independent on all other memory references |
2073 in LOOP. */ | 2339 in LOOP. */ |
2074 if (!ref_indep_loop_p (loop, ref)) | 2340 if (!ref_indep_loop_p (loop, ref)) |
2297 } | 2563 } |
2298 | 2564 |
2299 /* Moves invariants from loops. Only "expensive" invariants are moved out -- | 2565 /* Moves invariants from loops. Only "expensive" invariants are moved out -- |
2300 i.e. those that are likely to be win regardless of the register pressure. */ | 2566 i.e. those that are likely to be win regardless of the register pressure. */ |
2301 | 2567 |
2302 void | 2568 unsigned int |
2303 tree_ssa_lim (void) | 2569 tree_ssa_lim (void) |
2304 { | 2570 { |
2571 unsigned int todo; | |
2572 | |
2305 tree_ssa_lim_initialize (); | 2573 tree_ssa_lim_initialize (); |
2306 | 2574 |
2307 /* Gathers information about memory accesses in the loops. */ | 2575 /* Gathers information about memory accesses in the loops. */ |
2308 analyze_memory_references (); | 2576 analyze_memory_references (); |
2309 | 2577 |
2314 /* Execute store motion. Force the necessary invariants to be moved | 2582 /* Execute store motion. Force the necessary invariants to be moved |
2315 out of the loops as well. */ | 2583 out of the loops as well. */ |
2316 store_motion (); | 2584 store_motion (); |
2317 | 2585 |
2318 /* Move the expressions that are expensive enough. */ | 2586 /* Move the expressions that are expensive enough. */ |
2319 move_computations (); | 2587 todo = move_computations (); |
2320 | 2588 |
2321 tree_ssa_lim_finalize (); | 2589 tree_ssa_lim_finalize (); |
2322 } | 2590 |
2591 return todo; | |
2592 } |