Mercurial > hg > CbC > CbC_gcc
comparison gcc/loop-unroll.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
comparison
equal
deleted
inserted
replaced
131:84e7813d76e9 | 145:1830386684a0 |
---|---|
1 /* Loop unrolling. | 1 /* Loop unrolling. |
2 Copyright (C) 2002-2018 Free Software Foundation, Inc. | 2 Copyright (C) 2002-2020 Free Software Foundation, Inc. |
3 | 3 |
4 This file is part of GCC. | 4 This file is part of GCC. |
5 | 5 |
6 GCC is free software; you can redistribute it and/or modify it under | 6 GCC is free software; you can redistribute it and/or modify it under |
7 the terms of the GNU General Public License as published by the Free | 7 the terms of the GNU General Public License as published by the Free |
30 #include "emit-rtl.h" | 30 #include "emit-rtl.h" |
31 #include "recog.h" | 31 #include "recog.h" |
32 #include "profile.h" | 32 #include "profile.h" |
33 #include "cfgrtl.h" | 33 #include "cfgrtl.h" |
34 #include "cfgloop.h" | 34 #include "cfgloop.h" |
35 #include "params.h" | |
36 #include "dojump.h" | 35 #include "dojump.h" |
37 #include "expr.h" | 36 #include "expr.h" |
38 #include "dumpfile.h" | 37 #include "dumpfile.h" |
39 | 38 |
40 /* This pass performs loop unrolling. We only perform this | 39 /* This pass performs loop unrolling. We only perform this |
161 duplicated. */ | 160 duplicated. */ |
162 basic_block loop_exit; /* The loop exit basic block. */ | 161 basic_block loop_exit; /* The loop exit basic block. */ |
163 basic_block loop_preheader; /* The loop preheader basic block. */ | 162 basic_block loop_preheader; /* The loop preheader basic block. */ |
164 }; | 163 }; |
165 | 164 |
166 static void decide_unroll_stupid (struct loop *, int); | 165 static void decide_unroll_stupid (class loop *, int); |
167 static void decide_unroll_constant_iterations (struct loop *, int); | 166 static void decide_unroll_constant_iterations (class loop *, int); |
168 static void decide_unroll_runtime_iterations (struct loop *, int); | 167 static void decide_unroll_runtime_iterations (class loop *, int); |
169 static void unroll_loop_stupid (struct loop *); | 168 static void unroll_loop_stupid (class loop *); |
170 static void decide_unrolling (int); | 169 static void decide_unrolling (int); |
171 static void unroll_loop_constant_iterations (struct loop *); | 170 static void unroll_loop_constant_iterations (class loop *); |
172 static void unroll_loop_runtime_iterations (struct loop *); | 171 static void unroll_loop_runtime_iterations (class loop *); |
173 static struct opt_info *analyze_insns_in_loop (struct loop *); | 172 static struct opt_info *analyze_insns_in_loop (class loop *); |
174 static void opt_info_start_duplication (struct opt_info *); | 173 static void opt_info_start_duplication (struct opt_info *); |
175 static void apply_opt_in_copies (struct opt_info *, unsigned, bool, bool); | 174 static void apply_opt_in_copies (struct opt_info *, unsigned, bool, bool); |
176 static void free_opt_info (struct opt_info *); | 175 static void free_opt_info (struct opt_info *); |
177 static struct var_to_expand *analyze_insn_to_expand_var (struct loop*, rtx_insn *); | 176 static struct var_to_expand *analyze_insn_to_expand_var (class loop*, rtx_insn *); |
178 static bool referenced_in_one_insn_in_loop_p (struct loop *, rtx, int *); | 177 static bool referenced_in_one_insn_in_loop_p (class loop *, rtx, int *); |
179 static struct iv_to_split *analyze_iv_to_split_insn (rtx_insn *); | 178 static struct iv_to_split *analyze_iv_to_split_insn (rtx_insn *); |
180 static void expand_var_during_unrolling (struct var_to_expand *, rtx_insn *); | 179 static void expand_var_during_unrolling (struct var_to_expand *, rtx_insn *); |
181 static void insert_var_expansion_initialization (struct var_to_expand *, | 180 static void insert_var_expansion_initialization (struct var_to_expand *, |
182 basic_block); | 181 basic_block); |
183 static void combine_var_copies_in_loop_exit (struct var_to_expand *, | 182 static void combine_var_copies_in_loop_exit (struct var_to_expand *, |
187 /* Emit a message summarizing the unroll that will be | 186 /* Emit a message summarizing the unroll that will be |
188 performed for LOOP, along with the loop's location LOCUS, if | 187 performed for LOOP, along with the loop's location LOCUS, if |
189 appropriate given the dump or -fopt-info settings. */ | 188 appropriate given the dump or -fopt-info settings. */ |
190 | 189 |
191 static void | 190 static void |
192 report_unroll (struct loop *loop, dump_location_t locus) | 191 report_unroll (class loop *loop, dump_location_t locus) |
193 { | 192 { |
194 dump_flags_t report_flags = MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS; | 193 dump_flags_t report_flags = MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS; |
195 | 194 |
196 if (loop->lpt_decision.decision == LPT_NONE) | 195 if (loop->lpt_decision.decision == LPT_NONE) |
197 return; | 196 return; |
198 | 197 |
199 if (!dump_enabled_p ()) | 198 if (!dump_enabled_p ()) |
200 return; | 199 return; |
201 | 200 |
202 dump_printf_loc (report_flags, locus, | 201 dump_metadata_t metadata (report_flags, locus.get_impl_location ()); |
202 dump_printf_loc (metadata, locus.get_user_location (), | |
203 "loop unrolled %d times", | 203 "loop unrolled %d times", |
204 loop->lpt_decision.times); | 204 loop->lpt_decision.times); |
205 if (profile_info && loop->header->count.initialized_p ()) | 205 if (profile_info && loop->header->count.initialized_p ()) |
206 dump_printf (report_flags, | 206 dump_printf (metadata, |
207 " (header execution count %d)", | 207 " (header execution count %d)", |
208 (int)loop->header->count.to_gcov_type ()); | 208 (int)loop->header->count.to_gcov_type ()); |
209 | 209 |
210 dump_printf (report_flags, "\n"); | 210 dump_printf (metadata, "\n"); |
211 } | 211 } |
212 | 212 |
213 /* Decide whether unroll loops and how much. */ | 213 /* Decide whether unroll loops and how much. */ |
214 static void | 214 static void |
215 decide_unrolling (int flags) | 215 decide_unrolling (int flags) |
216 { | 216 { |
217 struct loop *loop; | 217 class loop *loop; |
218 | 218 |
219 /* Scan the loops, inner ones first. */ | 219 /* Scan the loops, inner ones first. */ |
220 FOR_EACH_LOOP (loop, LI_FROM_INNERMOST) | 220 FOR_EACH_LOOP (loop, LI_FROM_INNERMOST) |
221 { | 221 { |
222 loop->lpt_decision.decision = LPT_NONE; | 222 loop->lpt_decision.decision = LPT_NONE; |
276 | 276 |
277 /* Unroll LOOPS. */ | 277 /* Unroll LOOPS. */ |
278 void | 278 void |
279 unroll_loops (int flags) | 279 unroll_loops (int flags) |
280 { | 280 { |
281 struct loop *loop; | 281 class loop *loop; |
282 bool changed = false; | 282 bool changed = false; |
283 | 283 |
284 /* Now decide rest of unrolling. */ | 284 /* Now decide rest of unrolling. */ |
285 decide_unrolling (flags); | 285 decide_unrolling (flags); |
286 | 286 |
319 } | 319 } |
320 | 320 |
321 /* Check whether exit of the LOOP is at the end of loop body. */ | 321 /* Check whether exit of the LOOP is at the end of loop body. */ |
322 | 322 |
323 static bool | 323 static bool |
324 loop_exit_at_end_p (struct loop *loop) | 324 loop_exit_at_end_p (class loop *loop) |
325 { | 325 { |
326 struct niter_desc *desc = get_simple_loop_desc (loop); | 326 class niter_desc *desc = get_simple_loop_desc (loop); |
327 rtx_insn *insn; | 327 rtx_insn *insn; |
328 | 328 |
329 /* We should never have conditional in latch block. */ | 329 /* We should never have conditional in latch block. */ |
330 gcc_assert (desc->in_edge->dest != loop->header); | 330 gcc_assert (desc->in_edge->dest != loop->header); |
331 | 331 |
344 | 344 |
345 /* Decide whether to unroll LOOP iterating constant number of times | 345 /* Decide whether to unroll LOOP iterating constant number of times |
346 and how much. */ | 346 and how much. */ |
347 | 347 |
348 static void | 348 static void |
349 decide_unroll_constant_iterations (struct loop *loop, int flags) | 349 decide_unroll_constant_iterations (class loop *loop, int flags) |
350 { | 350 { |
351 unsigned nunroll, nunroll_by_av, best_copies, best_unroll = 0, n_copies, i; | 351 unsigned nunroll, nunroll_by_av, best_copies, best_unroll = 0, n_copies, i; |
352 struct niter_desc *desc; | 352 class niter_desc *desc; |
353 widest_int iterations; | 353 widest_int iterations; |
354 | 354 |
355 /* If we were not asked to unroll this loop, just return back silently. */ | 355 /* If we were not asked to unroll this loop, just return back silently. */ |
356 if (!(flags & UAP_UNROLL) && !loop->unroll) | 356 if (!(flags & UAP_UNROLL) && !loop->unroll) |
357 return; | 357 return; |
361 "considering unrolling loop with constant " | 361 "considering unrolling loop with constant " |
362 "number of iterations\n"); | 362 "number of iterations\n"); |
363 | 363 |
364 /* nunroll = total number of copies of the original loop body in | 364 /* nunroll = total number of copies of the original loop body in |
365 unrolled loop (i.e. if it is 2, we have to duplicate loop body once). */ | 365 unrolled loop (i.e. if it is 2, we have to duplicate loop body once). */ |
366 nunroll = PARAM_VALUE (PARAM_MAX_UNROLLED_INSNS) / loop->ninsns; | 366 nunroll = param_max_unrolled_insns / loop->ninsns; |
367 nunroll_by_av | 367 nunroll_by_av |
368 = PARAM_VALUE (PARAM_MAX_AVERAGE_UNROLLED_INSNS) / loop->av_ninsns; | 368 = param_max_average_unrolled_insns / loop->av_ninsns; |
369 if (nunroll > nunroll_by_av) | 369 if (nunroll > nunroll_by_av) |
370 nunroll = nunroll_by_av; | 370 nunroll = nunroll_by_av; |
371 if (nunroll > (unsigned) PARAM_VALUE (PARAM_MAX_UNROLL_TIMES)) | 371 if (nunroll > (unsigned) param_max_unroll_times) |
372 nunroll = PARAM_VALUE (PARAM_MAX_UNROLL_TIMES); | 372 nunroll = param_max_unroll_times; |
373 | 373 |
374 if (targetm.loop_unroll_adjust) | 374 if (targetm.loop_unroll_adjust) |
375 nunroll = targetm.loop_unroll_adjust (nunroll, loop); | 375 nunroll = targetm.loop_unroll_adjust (nunroll, loop); |
376 | 376 |
377 /* Skip big loops. */ | 377 /* Skip big loops. */ |
397 /* Check for an explicit unrolling factor. */ | 397 /* Check for an explicit unrolling factor. */ |
398 if (loop->unroll > 0 && loop->unroll < USHRT_MAX) | 398 if (loop->unroll > 0 && loop->unroll < USHRT_MAX) |
399 { | 399 { |
400 /* However we cannot unroll completely at the RTL level a loop with | 400 /* However we cannot unroll completely at the RTL level a loop with |
401 constant number of iterations; it should have been peeled instead. */ | 401 constant number of iterations; it should have been peeled instead. */ |
402 if ((unsigned) loop->unroll - 1 > desc->niter - 2) | 402 if (desc->niter == 0 || (unsigned) loop->unroll > desc->niter - 1) |
403 { | 403 { |
404 if (dump_file) | 404 if (dump_file) |
405 fprintf (dump_file, ";; Loop should have been peeled\n"); | 405 fprintf (dump_file, ";; Loop should have been peeled\n"); |
406 } | 406 } |
407 else | 407 else |
477 body; i++; | 477 body; i++; |
478 body; i++; | 478 body; i++; |
479 } | 479 } |
480 */ | 480 */ |
481 static void | 481 static void |
482 unroll_loop_constant_iterations (struct loop *loop) | 482 unroll_loop_constant_iterations (class loop *loop) |
483 { | 483 { |
484 unsigned HOST_WIDE_INT niter; | 484 unsigned HOST_WIDE_INT niter; |
485 unsigned exit_mod; | 485 unsigned exit_mod; |
486 unsigned i; | 486 unsigned i; |
487 edge e; | 487 edge e; |
488 unsigned max_unroll = loop->lpt_decision.times; | 488 unsigned max_unroll = loop->lpt_decision.times; |
489 struct niter_desc *desc = get_simple_loop_desc (loop); | 489 class niter_desc *desc = get_simple_loop_desc (loop); |
490 bool exit_at_end = loop_exit_at_end_p (loop); | 490 bool exit_at_end = loop_exit_at_end_p (loop); |
491 struct opt_info *opt_info = NULL; | 491 struct opt_info *opt_info = NULL; |
492 bool ok; | 492 bool ok; |
493 | 493 |
494 niter = desc->niter; | 494 niter = desc->niter; |
649 loop->nb_iterations_estimate | 649 loop->nb_iterations_estimate |
650 = wi::udiv_trunc (loop->nb_iterations_estimate, max_unroll + 1); | 650 = wi::udiv_trunc (loop->nb_iterations_estimate, max_unroll + 1); |
651 if (loop->any_likely_upper_bound) | 651 if (loop->any_likely_upper_bound) |
652 loop->nb_iterations_likely_upper_bound | 652 loop->nb_iterations_likely_upper_bound |
653 = wi::udiv_trunc (loop->nb_iterations_likely_upper_bound, max_unroll + 1); | 653 = wi::udiv_trunc (loop->nb_iterations_likely_upper_bound, max_unroll + 1); |
654 desc->niter_expr = GEN_INT (desc->niter); | 654 desc->niter_expr = gen_int_mode (desc->niter, desc->mode); |
655 | 655 |
656 /* Remove the edges. */ | 656 /* Remove the edges. */ |
657 FOR_EACH_VEC_ELT (remove_edges, i, e) | 657 FOR_EACH_VEC_ELT (remove_edges, i, e) |
658 remove_path (e); | 658 remove_path (e); |
659 | 659 |
664 } | 664 } |
665 | 665 |
666 /* Decide whether to unroll LOOP iterating runtime computable number of times | 666 /* Decide whether to unroll LOOP iterating runtime computable number of times |
667 and how much. */ | 667 and how much. */ |
668 static void | 668 static void |
669 decide_unroll_runtime_iterations (struct loop *loop, int flags) | 669 decide_unroll_runtime_iterations (class loop *loop, int flags) |
670 { | 670 { |
671 unsigned nunroll, nunroll_by_av, i; | 671 unsigned nunroll, nunroll_by_av, i; |
672 struct niter_desc *desc; | 672 class niter_desc *desc; |
673 widest_int iterations; | 673 widest_int iterations; |
674 | 674 |
675 /* If we were not asked to unroll this loop, just return back silently. */ | 675 /* If we were not asked to unroll this loop, just return back silently. */ |
676 if (!(flags & UAP_UNROLL) && !loop->unroll) | 676 if (!(flags & UAP_UNROLL) && !loop->unroll) |
677 return; | 677 return; |
681 "considering unrolling loop with runtime-" | 681 "considering unrolling loop with runtime-" |
682 "computable number of iterations\n"); | 682 "computable number of iterations\n"); |
683 | 683 |
684 /* nunroll = total number of copies of the original loop body in | 684 /* nunroll = total number of copies of the original loop body in |
685 unrolled loop (i.e. if it is 2, we have to duplicate loop body once. */ | 685 unrolled loop (i.e. if it is 2, we have to duplicate loop body once. */ |
686 nunroll = PARAM_VALUE (PARAM_MAX_UNROLLED_INSNS) / loop->ninsns; | 686 nunroll = param_max_unrolled_insns / loop->ninsns; |
687 nunroll_by_av = PARAM_VALUE (PARAM_MAX_AVERAGE_UNROLLED_INSNS) / loop->av_ninsns; | 687 nunroll_by_av = param_max_average_unrolled_insns / loop->av_ninsns; |
688 if (nunroll > nunroll_by_av) | 688 if (nunroll > nunroll_by_av) |
689 nunroll = nunroll_by_av; | 689 nunroll = nunroll_by_av; |
690 if (nunroll > (unsigned) PARAM_VALUE (PARAM_MAX_UNROLL_TIMES)) | 690 if (nunroll > (unsigned) param_max_unroll_times) |
691 nunroll = PARAM_VALUE (PARAM_MAX_UNROLL_TIMES); | 691 nunroll = param_max_unroll_times; |
692 | 692 |
693 if (targetm.loop_unroll_adjust) | 693 if (targetm.loop_unroll_adjust) |
694 nunroll = targetm.loop_unroll_adjust (nunroll, loop); | 694 nunroll = targetm.loop_unroll_adjust (nunroll, loop); |
695 | 695 |
696 if (loop->unroll > 0 && loop->unroll < USHRT_MAX) | 696 if (loop->unroll > 0 && loop->unroll < USHRT_MAX) |
878 body; i++; | 878 body; i++; |
879 body; i++; | 879 body; i++; |
880 } | 880 } |
881 */ | 881 */ |
882 static void | 882 static void |
883 unroll_loop_runtime_iterations (struct loop *loop) | 883 unroll_loop_runtime_iterations (class loop *loop) |
884 { | 884 { |
885 rtx old_niter, niter, tmp; | 885 rtx old_niter, niter, tmp; |
886 rtx_insn *init_code, *branch_code; | 886 rtx_insn *init_code, *branch_code; |
887 unsigned i, j; | 887 unsigned i, j; |
888 profile_probability p; | 888 profile_probability p; |
891 profile_count iter_count, new_count; | 891 profile_count iter_count, new_count; |
892 unsigned n_peel; | 892 unsigned n_peel; |
893 edge e; | 893 edge e; |
894 bool extra_zero_check, last_may_exit; | 894 bool extra_zero_check, last_may_exit; |
895 unsigned max_unroll = loop->lpt_decision.times; | 895 unsigned max_unroll = loop->lpt_decision.times; |
896 struct niter_desc *desc = get_simple_loop_desc (loop); | 896 class niter_desc *desc = get_simple_loop_desc (loop); |
897 bool exit_at_end = loop_exit_at_end_p (loop); | 897 bool exit_at_end = loop_exit_at_end_p (loop); |
898 struct opt_info *opt_info = NULL; | 898 struct opt_info *opt_info = NULL; |
899 bool ok; | 899 bool ok; |
900 | 900 |
901 if (flag_split_ivs_in_unroller | 901 if (flag_split_ivs_in_unroller |
1017 p = profile_probability::always ().apply_scale (1, i + 2); | 1017 p = profile_probability::always ().apply_scale (1, i + 2); |
1018 | 1018 |
1019 preheader = split_edge (loop_preheader_edge (loop)); | 1019 preheader = split_edge (loop_preheader_edge (loop)); |
1020 /* Add in count of edge from switch block. */ | 1020 /* Add in count of edge from switch block. */ |
1021 preheader->count += iter_count; | 1021 preheader->count += iter_count; |
1022 branch_code = compare_and_jump_seq (copy_rtx (niter), GEN_INT (j), EQ, | 1022 branch_code = compare_and_jump_seq (copy_rtx (niter), |
1023 block_label (preheader), p, | 1023 gen_int_mode (j, desc->mode), EQ, |
1024 NULL); | 1024 block_label (preheader), p, NULL); |
1025 | 1025 |
1026 /* We rely on the fact that the compare and jump cannot be optimized out, | 1026 /* We rely on the fact that the compare and jump cannot be optimized out, |
1027 and hence the cfg we create is correct. */ | 1027 and hence the cfg we create is correct. */ |
1028 gcc_assert (branch_code != NULL_RTX); | 1028 gcc_assert (branch_code != NULL_RTX); |
1029 | 1029 |
1149 max_unroll, num_loop_insns (loop)); | 1149 max_unroll, num_loop_insns (loop)); |
1150 } | 1150 } |
1151 | 1151 |
1152 /* Decide whether to unroll LOOP stupidly and how much. */ | 1152 /* Decide whether to unroll LOOP stupidly and how much. */ |
1153 static void | 1153 static void |
1154 decide_unroll_stupid (struct loop *loop, int flags) | 1154 decide_unroll_stupid (class loop *loop, int flags) |
1155 { | 1155 { |
1156 unsigned nunroll, nunroll_by_av, i; | 1156 unsigned nunroll, nunroll_by_av, i; |
1157 struct niter_desc *desc; | 1157 class niter_desc *desc; |
1158 widest_int iterations; | 1158 widest_int iterations; |
1159 | 1159 |
1160 /* If we were not asked to unroll this loop, just return back silently. */ | 1160 /* If we were not asked to unroll this loop, just return back silently. */ |
1161 if (!(flags & UAP_UNROLL_ALL) && !loop->unroll) | 1161 if (!(flags & UAP_UNROLL_ALL) && !loop->unroll) |
1162 return; | 1162 return; |
1164 if (dump_enabled_p ()) | 1164 if (dump_enabled_p ()) |
1165 dump_printf (MSG_NOTE, "considering unrolling loop stupidly\n"); | 1165 dump_printf (MSG_NOTE, "considering unrolling loop stupidly\n"); |
1166 | 1166 |
1167 /* nunroll = total number of copies of the original loop body in | 1167 /* nunroll = total number of copies of the original loop body in |
1168 unrolled loop (i.e. if it is 2, we have to duplicate loop body once. */ | 1168 unrolled loop (i.e. if it is 2, we have to duplicate loop body once. */ |
1169 nunroll = PARAM_VALUE (PARAM_MAX_UNROLLED_INSNS) / loop->ninsns; | 1169 nunroll = param_max_unrolled_insns / loop->ninsns; |
1170 nunroll_by_av | 1170 nunroll_by_av |
1171 = PARAM_VALUE (PARAM_MAX_AVERAGE_UNROLLED_INSNS) / loop->av_ninsns; | 1171 = param_max_average_unrolled_insns / loop->av_ninsns; |
1172 if (nunroll > nunroll_by_av) | 1172 if (nunroll > nunroll_by_av) |
1173 nunroll = nunroll_by_av; | 1173 nunroll = nunroll_by_av; |
1174 if (nunroll > (unsigned) PARAM_VALUE (PARAM_MAX_UNROLL_TIMES)) | 1174 if (nunroll > (unsigned) param_max_unroll_times) |
1175 nunroll = PARAM_VALUE (PARAM_MAX_UNROLL_TIMES); | 1175 nunroll = param_max_unroll_times; |
1176 | 1176 |
1177 if (targetm.loop_unroll_adjust) | 1177 if (targetm.loop_unroll_adjust) |
1178 nunroll = targetm.loop_unroll_adjust (nunroll, loop); | 1178 nunroll = targetm.loop_unroll_adjust (nunroll, loop); |
1179 | 1179 |
1180 if (loop->unroll > 0 && loop->unroll < USHRT_MAX) | 1180 if (loop->unroll > 0 && loop->unroll < USHRT_MAX) |
1247 if (!cond) break; | 1247 if (!cond) break; |
1248 body; | 1248 body; |
1249 } | 1249 } |
1250 */ | 1250 */ |
1251 static void | 1251 static void |
1252 unroll_loop_stupid (struct loop *loop) | 1252 unroll_loop_stupid (class loop *loop) |
1253 { | 1253 { |
1254 unsigned nunroll = loop->lpt_decision.times; | 1254 unsigned nunroll = loop->lpt_decision.times; |
1255 struct niter_desc *desc = get_simple_loop_desc (loop); | 1255 class niter_desc *desc = get_simple_loop_desc (loop); |
1256 struct opt_info *opt_info = NULL; | 1256 struct opt_info *opt_info = NULL; |
1257 bool ok; | 1257 bool ok; |
1258 | 1258 |
1259 if (flag_split_ivs_in_unroller | 1259 if (flag_split_ivs_in_unroller |
1260 || flag_variable_expansion_in_unroller) | 1260 || flag_variable_expansion_in_unroller) |
1298 /* Returns true if REG is referenced in one nondebug insn in LOOP. | 1298 /* Returns true if REG is referenced in one nondebug insn in LOOP. |
1299 Set *DEBUG_USES to the number of debug insns that reference the | 1299 Set *DEBUG_USES to the number of debug insns that reference the |
1300 variable. */ | 1300 variable. */ |
1301 | 1301 |
1302 static bool | 1302 static bool |
1303 referenced_in_one_insn_in_loop_p (struct loop *loop, rtx reg, | 1303 referenced_in_one_insn_in_loop_p (class loop *loop, rtx reg, |
1304 int *debug_uses) | 1304 int *debug_uses) |
1305 { | 1305 { |
1306 basic_block *body, bb; | 1306 basic_block *body, bb; |
1307 unsigned i; | 1307 unsigned i; |
1308 int count_ref = 0; | 1308 int count_ref = 0; |
1326 } | 1326 } |
1327 | 1327 |
1328 /* Reset the DEBUG_USES debug insns in LOOP that reference REG. */ | 1328 /* Reset the DEBUG_USES debug insns in LOOP that reference REG. */ |
1329 | 1329 |
1330 static void | 1330 static void |
1331 reset_debug_uses_in_loop (struct loop *loop, rtx reg, int debug_uses) | 1331 reset_debug_uses_in_loop (class loop *loop, rtx reg, int debug_uses) |
1332 { | 1332 { |
1333 basic_block *body, bb; | 1333 basic_block *body, bb; |
1334 unsigned i; | 1334 unsigned i; |
1335 rtx_insn *insn; | 1335 rtx_insn *insn; |
1336 | 1336 |
1375 Otherwise, allocate a VAR_TO_EXPAND structure, fill it with the relevant | 1375 Otherwise, allocate a VAR_TO_EXPAND structure, fill it with the relevant |
1376 information and return a pointer to it. | 1376 information and return a pointer to it. |
1377 */ | 1377 */ |
1378 | 1378 |
1379 static struct var_to_expand * | 1379 static struct var_to_expand * |
1380 analyze_insn_to_expand_var (struct loop *loop, rtx_insn *insn) | 1380 analyze_insn_to_expand_var (class loop *loop, rtx_insn *insn) |
1381 { | 1381 { |
1382 rtx set, dest, src; | 1382 rtx set, dest, src; |
1383 struct var_to_expand *ves; | 1383 struct var_to_expand *ves; |
1384 unsigned accum_pos; | 1384 unsigned accum_pos; |
1385 enum rtx_code code; | 1385 enum rtx_code code; |
1404 if (code == FMA && !flag_unsafe_math_optimizations) | 1404 if (code == FMA && !flag_unsafe_math_optimizations) |
1405 return NULL; | 1405 return NULL; |
1406 } | 1406 } |
1407 | 1407 |
1408 /* Hmm, this is a bit paradoxical. We know that INSN is a valid insn | 1408 /* Hmm, this is a bit paradoxical. We know that INSN is a valid insn |
1409 in MD. But if there is no optab to generate the insn, we can not | 1409 in MD. But if there is no optab to generate the insn, we cannot |
1410 perform the variable expansion. This can happen if an MD provides | 1410 perform the variable expansion. This can happen if an MD provides |
1411 an insn but not a named pattern to generate it, for example to avoid | 1411 an insn but not a named pattern to generate it, for example to avoid |
1412 producing code that needs additional mode switches like for x87/mmx. | 1412 producing code that needs additional mode switches like for x87/mmx. |
1413 | 1413 |
1414 So we check have_insn_for which looks for an optab for the operation | 1414 So we check have_insn_for which looks for an optab for the operation |
1516 | 1516 |
1517 static struct iv_to_split * | 1517 static struct iv_to_split * |
1518 analyze_iv_to_split_insn (rtx_insn *insn) | 1518 analyze_iv_to_split_insn (rtx_insn *insn) |
1519 { | 1519 { |
1520 rtx set, dest; | 1520 rtx set, dest; |
1521 struct rtx_iv iv; | 1521 class rtx_iv iv; |
1522 struct iv_to_split *ivts; | 1522 struct iv_to_split *ivts; |
1523 scalar_int_mode mode; | 1523 scalar_int_mode mode; |
1524 bool ok; | 1524 bool ok; |
1525 | 1525 |
1526 /* For now we just split the basic induction variables. Later this may be | 1526 /* For now we just split the basic induction variables. Later this may be |
1568 Return a OPT_INFO struct with the relevant hash tables filled | 1568 Return a OPT_INFO struct with the relevant hash tables filled |
1569 with all insns to be optimized. The FIRST_NEW_BLOCK field | 1569 with all insns to be optimized. The FIRST_NEW_BLOCK field |
1570 is undefined for the return value. */ | 1570 is undefined for the return value. */ |
1571 | 1571 |
1572 static struct opt_info * | 1572 static struct opt_info * |
1573 analyze_insns_in_loop (struct loop *loop) | 1573 analyze_insns_in_loop (class loop *loop) |
1574 { | 1574 { |
1575 basic_block *body, bb; | 1575 basic_block *body, bb; |
1576 unsigned i; | 1576 unsigned i; |
1577 struct opt_info *opt_info = XCNEW (struct opt_info); | 1577 struct opt_info *opt_info = XCNEW (struct opt_info); |
1578 rtx_insn *insn; | 1578 rtx_insn *insn; |
1821 set = single_set (insn); | 1821 set = single_set (insn); |
1822 gcc_assert (set); | 1822 gcc_assert (set); |
1823 | 1823 |
1824 /* Generate a new register only if the expansion limit has not been | 1824 /* Generate a new register only if the expansion limit has not been |
1825 reached. Else reuse an already existing expansion. */ | 1825 reached. Else reuse an already existing expansion. */ |
1826 if (PARAM_VALUE (PARAM_MAX_VARIABLE_EXPANSIONS) > ve->expansion_count) | 1826 if (param_max_variable_expansions > ve->expansion_count) |
1827 { | 1827 { |
1828 really_new_expansion = true; | 1828 really_new_expansion = true; |
1829 new_reg = gen_reg_rtx (GET_MODE (ve->reg)); | 1829 new_reg = gen_reg_rtx (GET_MODE (ve->reg)); |
1830 } | 1830 } |
1831 else | 1831 else |