00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 #include "config.h"
00052 #include "system.h"
00053 #include "coretypes.h"
00054 #include "tm.h"
00055 #include "rtl.h"
00056 #include "hard-reg-set.h"
00057 #include "obstack.h"
00058 #include "basic-block.h"
00059 #include "cfgloop.h"
00060 #include "expr.h"
00061 #include "intl.h"
00062 #include "output.h"
00063 #include "toplev.h"
00064 #include "df.h"
00065 #include "hashtab.h"
00066
00067
00068
00069 enum iv_grd_result
00070 {
00071
00072
00073 GRD_INVALID,
00074
00075
00076
00077 GRD_INVARIANT,
00078
00079
00080
00081 GRD_MAYBE_BIV,
00082
00083
00084 GRD_SINGLE_DOM
00085 };
00086
00087
00088
00089 struct biv_entry
00090 {
00091 unsigned regno;
00092 struct rtx_iv iv;
00093 };
00094
00095
00096 #define DF_REF_IV(REF) ((struct rtx_iv *) DF_REF_DATA (REF))
00097 #define DF_REF_IV_SET(REF, IV) DF_REF_DATA (REF) = (IV)
00098
00099
00100
00101 static struct loop *current_loop;
00102
00103
00104
00105 static struct df *df = NULL;
00106
00107
00108
00109 static htab_t bivs;
00110
00111
00112 struct df *
00113 iv_current_loop_df (void)
00114 {
00115 return df;
00116 }
00117
00118 static bool iv_analyze_op (rtx, rtx, struct rtx_iv *);
00119
00120
00121
00122 extern void dump_iv_info (FILE *, struct rtx_iv *);
00123 void
00124 dump_iv_info (FILE *file, struct rtx_iv *iv)
00125 {
00126 if (!iv->base)
00127 {
00128 fprintf (file, "not simple");
00129 return;
00130 }
00131
00132 if (iv->step == const0_rtx
00133 && !iv->first_special)
00134 fprintf (file, "invariant ");
00135
00136 print_rtl (file, iv->base);
00137 if (iv->step != const0_rtx)
00138 {
00139 fprintf (file, " + ");
00140 print_rtl (file, iv->step);
00141 fprintf (file, " * iteration");
00142 }
00143 fprintf (file, " (in %s)", GET_MODE_NAME (iv->mode));
00144
00145 if (iv->mode != iv->extend_mode)
00146 fprintf (file, " %s to %s",
00147 rtx_name[iv->extend],
00148 GET_MODE_NAME (iv->extend_mode));
00149
00150 if (iv->mult != const1_rtx)
00151 {
00152 fprintf (file, " * ");
00153 print_rtl (file, iv->mult);
00154 }
00155 if (iv->delta != const0_rtx)
00156 {
00157 fprintf (file, " + ");
00158 print_rtl (file, iv->delta);
00159 }
00160 if (iv->first_special)
00161 fprintf (file, " (first special)");
00162 }
00163
00164
00165
00166
00167 rtx
00168 lowpart_subreg (enum machine_mode outer_mode, rtx expr,
00169 enum machine_mode inner_mode)
00170 {
00171 return simplify_gen_subreg (outer_mode, expr, inner_mode,
00172 subreg_lowpart_offset (outer_mode, inner_mode));
00173 }
00174
00175
00176
00177 static bool
00178 simple_reg_p (rtx reg)
00179 {
00180 unsigned r;
00181
00182 if (GET_CODE (reg) == SUBREG)
00183 {
00184 if (!subreg_lowpart_p (reg))
00185 return false;
00186 reg = SUBREG_REG (reg);
00187 }
00188
00189 if (!REG_P (reg))
00190 return false;
00191
00192 r = REGNO (reg);
00193 if (HARD_REGISTER_NUM_P (r))
00194 return false;
00195
00196 if (GET_MODE_CLASS (GET_MODE (reg)) != MODE_INT)
00197 return false;
00198
00199 return true;
00200 }
00201
00202
00203
00204 static void
00205 clear_iv_info (void)
00206 {
00207 unsigned i, n_defs = DF_DEFS_SIZE (df);
00208 struct rtx_iv *iv;
00209 struct df_ref *def;
00210
00211 for (i = 0; i < n_defs; i++)
00212 {
00213 def = DF_DEFS_GET (df, i);
00214 iv = DF_REF_IV (def);
00215 if (!iv)
00216 continue;
00217 free (iv);
00218 DF_REF_IV_SET (def, NULL);
00219 }
00220
00221 htab_empty (bivs);
00222 }
00223
00224
00225
00226 static hashval_t
00227 biv_hash (const void *b)
00228 {
00229 return ((const struct biv_entry *) b)->regno;
00230 }
00231
00232
00233
00234 static int
00235 biv_eq (const void *b, const void *r)
00236 {
00237 return ((const struct biv_entry *) b)->regno == REGNO ((rtx) r);
00238 }
00239
00240
00241
00242 void
00243 iv_analysis_loop_init (struct loop *loop)
00244 {
00245 basic_block *body = get_loop_body_in_dom_order (loop), bb;
00246 bitmap blocks = BITMAP_ALLOC (NULL);
00247 unsigned i;
00248 bool first_time = (df == NULL);
00249
00250 current_loop = loop;
00251
00252
00253 if (first_time)
00254 {
00255 df = df_init (DF_HARD_REGS | DF_EQUIV_NOTES);
00256 df_chain_add_problem (df, DF_UD_CHAIN);
00257 bivs = htab_create (10, biv_hash, biv_eq, free);
00258 }
00259 else
00260 clear_iv_info ();
00261
00262 for (i = 0; i < loop->num_nodes; i++)
00263 {
00264 bb = body[i];
00265 bitmap_set_bit (blocks, bb->index);
00266 }
00267 df_set_blocks (df, blocks);
00268 df_analyze (df);
00269 BITMAP_FREE (blocks);
00270 free (body);
00271 }
00272
00273
00274
00275
00276
00277
00278 static bool
00279 latch_dominating_def (rtx reg, struct df_ref **def)
00280 {
00281 struct df_ref *single_rd = NULL, *adef;
00282 unsigned regno = REGNO (reg);
00283 struct df_reg_info *reg_info = DF_REG_DEF_GET (df, regno);
00284 struct df_rd_bb_info *bb_info = DF_RD_BB_INFO (df, current_loop->latch);
00285
00286 for (adef = reg_info->reg_chain; adef; adef = adef->next_reg)
00287 {
00288 if (!bitmap_bit_p (bb_info->out, DF_REF_ID (adef)))
00289 continue;
00290
00291
00292 if (single_rd)
00293 return false;
00294
00295 if (!just_once_each_iteration_p (current_loop, DF_REF_BB (adef)))
00296 return false;
00297
00298 single_rd = adef;
00299 }
00300
00301 *def = single_rd;
00302 return true;
00303 }
00304
00305
00306
00307 static enum iv_grd_result
00308 iv_get_reaching_def (rtx insn, rtx reg, struct df_ref **def)
00309 {
00310 struct df_ref *use, *adef;
00311 basic_block def_bb, use_bb;
00312 rtx def_insn;
00313 bool dom_p;
00314
00315 *def = NULL;
00316 if (!simple_reg_p (reg))
00317 return GRD_INVALID;
00318 if (GET_CODE (reg) == SUBREG)
00319 reg = SUBREG_REG (reg);
00320 gcc_assert (REG_P (reg));
00321
00322 use = df_find_use (df, insn, reg);
00323 gcc_assert (use != NULL);
00324
00325 if (!DF_REF_CHAIN (use))
00326 return GRD_INVARIANT;
00327
00328
00329 if (DF_REF_CHAIN (use)->next)
00330 return GRD_INVALID;
00331
00332 adef = DF_REF_CHAIN (use)->ref;
00333 def_insn = DF_REF_INSN (adef);
00334 def_bb = DF_REF_BB (adef);
00335 use_bb = BLOCK_FOR_INSN (insn);
00336
00337 if (use_bb == def_bb)
00338 dom_p = (DF_INSN_LUID (df, def_insn) < DF_INSN_LUID (df, insn));
00339 else
00340 dom_p = dominated_by_p (CDI_DOMINATORS, use_bb, def_bb);
00341
00342 if (dom_p)
00343 {
00344 *def = adef;
00345 return GRD_SINGLE_DOM;
00346 }
00347
00348
00349
00350
00351 if (just_once_each_iteration_p (current_loop, def_bb))
00352 return GRD_MAYBE_BIV;
00353
00354 return GRD_INVALID;
00355 }
00356
00357
00358
00359
00360 static bool
00361 iv_constant (struct rtx_iv *iv, rtx cst, enum machine_mode mode)
00362 {
00363 if (mode == VOIDmode)
00364 mode = GET_MODE (cst);
00365
00366 iv->mode = mode;
00367 iv->base = cst;
00368 iv->step = const0_rtx;
00369 iv->first_special = false;
00370 iv->extend = UNKNOWN;
00371 iv->extend_mode = iv->mode;
00372 iv->delta = const0_rtx;
00373 iv->mult = const1_rtx;
00374
00375 return true;
00376 }
00377
00378
00379
00380 static bool
00381 iv_subreg (struct rtx_iv *iv, enum machine_mode mode)
00382 {
00383
00384 if (iv->step == const0_rtx
00385 && !iv->first_special)
00386 {
00387 rtx val = get_iv_value (iv, const0_rtx);
00388 val = lowpart_subreg (mode, val, iv->extend_mode);
00389
00390 iv->base = val;
00391 iv->extend = UNKNOWN;
00392 iv->mode = iv->extend_mode = mode;
00393 iv->delta = const0_rtx;
00394 iv->mult = const1_rtx;
00395 return true;
00396 }
00397
00398 if (iv->extend_mode == mode)
00399 return true;
00400
00401 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (iv->mode))
00402 return false;
00403
00404 iv->extend = UNKNOWN;
00405 iv->mode = mode;
00406
00407 iv->base = simplify_gen_binary (PLUS, iv->extend_mode, iv->delta,
00408 simplify_gen_binary (MULT, iv->extend_mode,
00409 iv->base, iv->mult));
00410 iv->step = simplify_gen_binary (MULT, iv->extend_mode, iv->step, iv->mult);
00411 iv->mult = const1_rtx;
00412 iv->delta = const0_rtx;
00413 iv->first_special = false;
00414
00415 return true;
00416 }
00417
00418
00419
00420 static bool
00421 iv_extend (struct rtx_iv *iv, enum rtx_code extend, enum machine_mode mode)
00422 {
00423
00424 if (iv->step == const0_rtx
00425 && !iv->first_special)
00426 {
00427 rtx val = get_iv_value (iv, const0_rtx);
00428 val = simplify_gen_unary (extend, mode, val, iv->extend_mode);
00429
00430 iv->base = val;
00431 iv->extend = UNKNOWN;
00432 iv->mode = iv->extend_mode = mode;
00433 iv->delta = const0_rtx;
00434 iv->mult = const1_rtx;
00435 return true;
00436 }
00437
00438 if (mode != iv->extend_mode)
00439 return false;
00440
00441 if (iv->extend != UNKNOWN
00442 && iv->extend != extend)
00443 return false;
00444
00445 iv->extend = extend;
00446
00447 return true;
00448 }
00449
00450
00451
00452 static bool
00453 iv_neg (struct rtx_iv *iv)
00454 {
00455 if (iv->extend == UNKNOWN)
00456 {
00457 iv->base = simplify_gen_unary (NEG, iv->extend_mode,
00458 iv->base, iv->extend_mode);
00459 iv->step = simplify_gen_unary (NEG, iv->extend_mode,
00460 iv->step, iv->extend_mode);
00461 }
00462 else
00463 {
00464 iv->delta = simplify_gen_unary (NEG, iv->extend_mode,
00465 iv->delta, iv->extend_mode);
00466 iv->mult = simplify_gen_unary (NEG, iv->extend_mode,
00467 iv->mult, iv->extend_mode);
00468 }
00469
00470 return true;
00471 }
00472
00473
00474
00475 static bool
00476 iv_add (struct rtx_iv *iv0, struct rtx_iv *iv1, enum rtx_code op)
00477 {
00478 enum machine_mode mode;
00479 rtx arg;
00480
00481
00482 if (iv0->extend == UNKNOWN
00483 && iv0->mode == iv0->extend_mode
00484 && iv0->step == const0_rtx
00485 && GET_MODE_SIZE (iv0->extend_mode) < GET_MODE_SIZE (iv1->extend_mode))
00486 {
00487 iv0->extend_mode = iv1->extend_mode;
00488 iv0->base = simplify_gen_unary (ZERO_EXTEND, iv0->extend_mode,
00489 iv0->base, iv0->mode);
00490 }
00491 if (iv1->extend == UNKNOWN
00492 && iv1->mode == iv1->extend_mode
00493 && iv1->step == const0_rtx
00494 && GET_MODE_SIZE (iv1->extend_mode) < GET_MODE_SIZE (iv0->extend_mode))
00495 {
00496 iv1->extend_mode = iv0->extend_mode;
00497 iv1->base = simplify_gen_unary (ZERO_EXTEND, iv1->extend_mode,
00498 iv1->base, iv1->mode);
00499 }
00500
00501 mode = iv0->extend_mode;
00502 if (mode != iv1->extend_mode)
00503 return false;
00504
00505 if (iv0->extend == UNKNOWN && iv1->extend == UNKNOWN)
00506 {
00507 if (iv0->mode != iv1->mode)
00508 return false;
00509
00510 iv0->base = simplify_gen_binary (op, mode, iv0->base, iv1->base);
00511 iv0->step = simplify_gen_binary (op, mode, iv0->step, iv1->step);
00512
00513 return true;
00514 }
00515
00516
00517 if (iv1->extend == UNKNOWN
00518 && iv1->mode == mode
00519 && iv1->step == const0_rtx)
00520 {
00521 iv0->delta = simplify_gen_binary (op, mode, iv0->delta, iv1->base);
00522 return true;
00523 }
00524
00525 if (iv0->extend == UNKNOWN
00526 && iv0->mode == mode
00527 && iv0->step == const0_rtx)
00528 {
00529 arg = iv0->base;
00530 *iv0 = *iv1;
00531 if (op == MINUS
00532 && !iv_neg (iv0))
00533 return false;
00534
00535 iv0->delta = simplify_gen_binary (PLUS, mode, iv0->delta, arg);
00536 return true;
00537 }
00538
00539 return false;
00540 }
00541
00542
00543
00544 static bool
00545 iv_mult (struct rtx_iv *iv, rtx mby)
00546 {
00547 enum machine_mode mode = iv->extend_mode;
00548
00549 if (GET_MODE (mby) != VOIDmode
00550 && GET_MODE (mby) != mode)
00551 return false;
00552
00553 if (iv->extend == UNKNOWN)
00554 {
00555 iv->base = simplify_gen_binary (MULT, mode, iv->base, mby);
00556 iv->step = simplify_gen_binary (MULT, mode, iv->step, mby);
00557 }
00558 else
00559 {
00560 iv->delta = simplify_gen_binary (MULT, mode, iv->delta, mby);
00561 iv->mult = simplify_gen_binary (MULT, mode, iv->mult, mby);
00562 }
00563
00564 return true;
00565 }
00566
00567
00568
00569 static bool
00570 iv_shift (struct rtx_iv *iv, rtx mby)
00571 {
00572 enum machine_mode mode = iv->extend_mode;
00573
00574 if (GET_MODE (mby) != VOIDmode
00575 && GET_MODE (mby) != mode)
00576 return false;
00577
00578 if (iv->extend == UNKNOWN)
00579 {
00580 iv->base = simplify_gen_binary (ASHIFT, mode, iv->base, mby);
00581 iv->step = simplify_gen_binary (ASHIFT, mode, iv->step, mby);
00582 }
00583 else
00584 {
00585 iv->delta = simplify_gen_binary (ASHIFT, mode, iv->delta, mby);
00586 iv->mult = simplify_gen_binary (ASHIFT, mode, iv->mult, mby);
00587 }
00588
00589 return true;
00590 }
00591
00592
00593
00594
00595
00596 static bool
00597 get_biv_step_1 (struct df_ref *def, rtx reg,
00598 rtx *inner_step, enum machine_mode *inner_mode,
00599 enum rtx_code *extend, enum machine_mode outer_mode,
00600 rtx *outer_step)
00601 {
00602 rtx set, rhs, op0 = NULL_RTX, op1 = NULL_RTX;
00603 rtx next, nextr, tmp;
00604 enum rtx_code code;
00605 rtx insn = DF_REF_INSN (def);
00606 struct df_ref *next_def;
00607 enum iv_grd_result res;
00608
00609 set = single_set (insn);
00610 if (!set)
00611 return false;
00612
00613 rhs = find_reg_equal_equiv_note (insn);
00614 if (rhs)
00615 rhs = XEXP (rhs, 0);
00616 else
00617 rhs = SET_SRC (set);
00618
00619 code = GET_CODE (rhs);
00620 switch (code)
00621 {
00622 case SUBREG:
00623 case REG:
00624 next = rhs;
00625 break;
00626
00627 case PLUS:
00628 case MINUS:
00629 op0 = XEXP (rhs, 0);
00630 op1 = XEXP (rhs, 1);
00631
00632 if (code == PLUS && CONSTANT_P (op0))
00633 {
00634 tmp = op0; op0 = op1; op1 = tmp;
00635 }
00636
00637 if (!simple_reg_p (op0)
00638 || !CONSTANT_P (op1))
00639 return false;
00640
00641 if (GET_MODE (rhs) != outer_mode)
00642 {
00643
00644
00645
00646
00647
00648
00649
00650
00651 if (GET_CODE (op0) != SUBREG)
00652 return false;
00653 if (GET_MODE (SUBREG_REG (op0)) != outer_mode)
00654 return false;
00655 }
00656
00657 next = op0;
00658 break;
00659
00660 case SIGN_EXTEND:
00661 case ZERO_EXTEND:
00662 if (GET_MODE (rhs) != outer_mode)
00663 return false;
00664
00665 op0 = XEXP (rhs, 0);
00666 if (!simple_reg_p (op0))
00667 return false;
00668
00669 next = op0;
00670 break;
00671
00672 default:
00673 return false;
00674 }
00675
00676 if (GET_CODE (next) == SUBREG)
00677 {
00678 if (!subreg_lowpart_p (next))
00679 return false;
00680
00681 nextr = SUBREG_REG (next);
00682 if (GET_MODE (nextr) != outer_mode)
00683 return false;
00684 }
00685 else
00686 nextr = next;
00687
00688 res = iv_get_reaching_def (insn, nextr, &next_def);
00689
00690 if (res == GRD_INVALID || res == GRD_INVARIANT)
00691 return false;
00692
00693 if (res == GRD_MAYBE_BIV)
00694 {
00695 if (!rtx_equal_p (nextr, reg))
00696 return false;
00697
00698 *inner_step = const0_rtx;
00699 *extend = UNKNOWN;
00700 *inner_mode = outer_mode;
00701 *outer_step = const0_rtx;
00702 }
00703 else if (!get_biv_step_1 (next_def, reg,
00704 inner_step, inner_mode, extend, outer_mode,
00705 outer_step))
00706 return false;
00707
00708 if (GET_CODE (next) == SUBREG)
00709 {
00710 enum machine_mode amode = GET_MODE (next);
00711
00712 if (GET_MODE_SIZE (amode) > GET_MODE_SIZE (*inner_mode))
00713 return false;
00714
00715 *inner_mode = amode;
00716 *inner_step = simplify_gen_binary (PLUS, outer_mode,
00717 *inner_step, *outer_step);
00718 *outer_step = const0_rtx;
00719 *extend = UNKNOWN;
00720 }
00721
00722 switch (code)
00723 {
00724 case REG:
00725 case SUBREG:
00726 break;
00727
00728 case PLUS:
00729 case MINUS:
00730 if (*inner_mode == outer_mode
00731
00732 || GET_MODE (rhs) != outer_mode)
00733 *inner_step = simplify_gen_binary (code, outer_mode,
00734 *inner_step, op1);
00735 else
00736 *outer_step = simplify_gen_binary (code, outer_mode,
00737 *outer_step, op1);
00738 break;
00739
00740 case SIGN_EXTEND:
00741 case ZERO_EXTEND:
00742 gcc_assert (GET_MODE (op0) == *inner_mode
00743 && *extend == UNKNOWN
00744 && *outer_step == const0_rtx);
00745
00746 *extend = code;
00747 break;
00748
00749 default:
00750 return false;
00751 }
00752
00753 return true;
00754 }
00755
00756
00757
00758
00759
00760
00761
00762
00763 static bool
00764 get_biv_step (struct df_ref *last_def, rtx reg, rtx *inner_step,
00765 enum machine_mode *inner_mode, enum rtx_code *extend,
00766 enum machine_mode *outer_mode, rtx *outer_step)
00767 {
00768 *outer_mode = GET_MODE (reg);
00769
00770 if (!get_biv_step_1 (last_def, reg,
00771 inner_step, inner_mode, extend, *outer_mode,
00772 outer_step))
00773 return false;
00774
00775 gcc_assert ((*inner_mode == *outer_mode) != (*extend != UNKNOWN));
00776 gcc_assert (*inner_mode != *outer_mode || *outer_step == const0_rtx);
00777
00778 return true;
00779 }
00780
00781
00782
00783 static void
00784 record_iv (struct df_ref *def, struct rtx_iv *iv)
00785 {
00786 struct rtx_iv *recorded_iv = XNEW (struct rtx_iv);
00787
00788 *recorded_iv = *iv;
00789 DF_REF_IV_SET (def, recorded_iv);
00790 }
00791
00792
00793
00794
00795 static bool
00796 analyzed_for_bivness_p (rtx def, struct rtx_iv *iv)
00797 {
00798 struct biv_entry *biv = htab_find_with_hash (bivs, def, REGNO (def));
00799
00800 if (!biv)
00801 return false;
00802
00803 *iv = biv->iv;
00804 return true;
00805 }
00806
00807 static void
00808 record_biv (rtx def, struct rtx_iv *iv)
00809 {
00810 struct biv_entry *biv = XNEW (struct biv_entry);
00811 void **slot = htab_find_slot_with_hash (bivs, def, REGNO (def), INSERT);
00812
00813 biv->regno = REGNO (def);
00814 biv->iv = *iv;
00815 gcc_assert (!*slot);
00816 *slot = biv;
00817 }
00818
00819
00820
00821
00822 static bool
00823 iv_analyze_biv (rtx def, struct rtx_iv *iv)
00824 {
00825 rtx inner_step, outer_step;
00826 enum machine_mode inner_mode, outer_mode;
00827 enum rtx_code extend;
00828 struct df_ref *last_def;
00829
00830 if (dump_file)
00831 {
00832 fprintf (dump_file, "Analyzing ");
00833 print_rtl (dump_file, def);
00834 fprintf (dump_file, " for bivness.\n");
00835 }
00836
00837 if (!REG_P (def))
00838 {
00839 if (!CONSTANT_P (def))
00840 return false;
00841
00842 return iv_constant (iv, def, VOIDmode);
00843 }
00844
00845 if (!latch_dominating_def (def, &last_def))
00846 {
00847 if (dump_file)
00848 fprintf (dump_file, " not simple.\n");
00849 return false;
00850 }
00851
00852 if (!last_def)
00853 return iv_constant (iv, def, VOIDmode);
00854
00855 if (analyzed_for_bivness_p (def, iv))
00856 {
00857 if (dump_file)
00858 fprintf (dump_file, " already analysed.\n");
00859 return iv->base != NULL_RTX;
00860 }
00861
00862 if (!get_biv_step (last_def, def, &inner_step, &inner_mode, &extend,
00863 &outer_mode, &outer_step))
00864 {
00865 iv->base = NULL_RTX;
00866 goto end;
00867 }
00868
00869
00870
00871
00872
00873
00874
00875 iv->base = simplify_gen_binary (MINUS, outer_mode, def, outer_step);
00876 iv->step = simplify_gen_binary (PLUS, outer_mode, inner_step, outer_step);
00877 iv->mode = inner_mode;
00878 iv->extend_mode = outer_mode;
00879 iv->extend = extend;
00880 iv->mult = const1_rtx;
00881 iv->delta = outer_step;
00882 iv->first_special = inner_mode != outer_mode;
00883
00884 end:
00885 if (dump_file)
00886 {
00887 fprintf (dump_file, " ");
00888 dump_iv_info (dump_file, iv);
00889 fprintf (dump_file, "\n");
00890 }
00891
00892 record_biv (def, iv);
00893 return iv->base != NULL_RTX;
00894 }
00895
00896
00897
00898
00899 bool
00900 iv_analyze_expr (rtx insn, rtx rhs, enum machine_mode mode, struct rtx_iv *iv)
00901 {
00902 rtx mby = NULL_RTX, tmp;
00903 rtx op0 = NULL_RTX, op1 = NULL_RTX;
00904 struct rtx_iv iv0, iv1;
00905 enum rtx_code code = GET_CODE (rhs);
00906 enum machine_mode omode = mode;
00907
00908 iv->mode = VOIDmode;
00909 iv->base = NULL_RTX;
00910 iv->step = NULL_RTX;
00911
00912 gcc_assert (GET_MODE (rhs) == mode || GET_MODE (rhs) == VOIDmode);
00913
00914 if (CONSTANT_P (rhs)
00915 || REG_P (rhs)
00916 || code == SUBREG)
00917 {
00918 if (!iv_analyze_op (insn, rhs, iv))
00919 return false;
00920
00921 if (iv->mode == VOIDmode)
00922 {
00923 iv->mode = mode;
00924 iv->extend_mode = mode;
00925 }
00926
00927 return true;
00928 }
00929
00930 switch (code)
00931 {
00932 case REG:
00933 op0 = rhs;
00934 break;
00935
00936 case SIGN_EXTEND:
00937 case ZERO_EXTEND:
00938 case NEG:
00939 op0 = XEXP (rhs, 0);
00940 omode = GET_MODE (op0);
00941 break;
00942
00943 case PLUS:
00944 case MINUS:
00945 op0 = XEXP (rhs, 0);
00946 op1 = XEXP (rhs, 1);
00947 break;
00948
00949 case MULT:
00950 op0 = XEXP (rhs, 0);
00951 mby = XEXP (rhs, 1);
00952 if (!CONSTANT_P (mby))
00953 {
00954 tmp = op0;
00955 op0 = mby;
00956 mby = tmp;
00957 }
00958 if (!CONSTANT_P (mby))
00959 return false;
00960 break;
00961
00962 case ASHIFT:
00963 op0 = XEXP (rhs, 0);
00964 mby = XEXP (rhs, 1);
00965 if (!CONSTANT_P (mby))
00966 return false;
00967 break;
00968
00969 default:
00970 return false;
00971 }
00972
00973 if (op0
00974 && !iv_analyze_expr (insn, op0, omode, &iv0))
00975 return false;
00976
00977 if (op1
00978 && !iv_analyze_expr (insn, op1, omode, &iv1))
00979 return false;
00980
00981 switch (code)
00982 {
00983 case SIGN_EXTEND:
00984 case ZERO_EXTEND:
00985 if (!iv_extend (&iv0, code, mode))
00986 return false;
00987 break;
00988
00989 case NEG:
00990 if (!iv_neg (&iv0))
00991 return false;
00992 break;
00993
00994 case PLUS:
00995 case MINUS:
00996 if (!iv_add (&iv0, &iv1, code))
00997 return false;
00998 break;
00999
01000 case MULT:
01001 if (!iv_mult (&iv0, mby))
01002 return false;
01003 break;
01004
01005 case ASHIFT:
01006 if (!iv_shift (&iv0, mby))
01007 return false;
01008 break;
01009
01010 default:
01011 break;
01012 }
01013
01014 *iv = iv0;
01015 return iv->base != NULL_RTX;
01016 }
01017
01018
01019
01020 static bool
01021 iv_analyze_def (struct df_ref *def, struct rtx_iv *iv)
01022 {
01023 rtx insn = DF_REF_INSN (def);
01024 rtx reg = DF_REF_REG (def);
01025 rtx set, rhs;
01026
01027 if (dump_file)
01028 {
01029 fprintf (dump_file, "Analysing def of ");
01030 print_rtl (dump_file, reg);
01031 fprintf (dump_file, " in insn ");
01032 print_rtl_single (dump_file, insn);
01033 }
01034
01035 if (DF_REF_IV (def))
01036 {
01037 if (dump_file)
01038 fprintf (dump_file, " already analysed.\n");
01039 *iv = *DF_REF_IV (def);
01040 return iv->base != NULL_RTX;
01041 }
01042
01043 iv->mode = VOIDmode;
01044 iv->base = NULL_RTX;
01045 iv->step = NULL_RTX;
01046
01047 set = single_set (insn);
01048 if (!set || SET_DEST (set) != reg)
01049 return false;
01050
01051 rhs = find_reg_equal_equiv_note (insn);
01052 if (rhs)
01053 rhs = XEXP (rhs, 0);
01054 else
01055 rhs = SET_SRC (set);
01056
01057 iv_analyze_expr (insn, rhs, GET_MODE (reg), iv);
01058 record_iv (def, iv);
01059
01060 if (dump_file)
01061 {
01062 print_rtl (dump_file, reg);
01063 fprintf (dump_file, " in insn ");
01064 print_rtl_single (dump_file, insn);
01065 fprintf (dump_file, " is ");
01066 dump_iv_info (dump_file, iv);
01067 fprintf (dump_file, "\n");
01068 }
01069
01070 return iv->base != NULL_RTX;
01071 }
01072
01073
01074
01075 static bool
01076 iv_analyze_op (rtx insn, rtx op, struct rtx_iv *iv)
01077 {
01078 struct df_ref *def = NULL;
01079 enum iv_grd_result res;
01080
01081 if (dump_file)
01082 {
01083 fprintf (dump_file, "Analysing operand ");
01084 print_rtl (dump_file, op);
01085 fprintf (dump_file, " of insn ");
01086 print_rtl_single (dump_file, insn);
01087 }
01088
01089 if (CONSTANT_P (op))
01090 res = GRD_INVARIANT;
01091 else if (GET_CODE (op) == SUBREG)
01092 {
01093 if (!subreg_lowpart_p (op))
01094 return false;
01095
01096 if (!iv_analyze_op (insn, SUBREG_REG (op), iv))
01097 return false;
01098
01099 return iv_subreg (iv, GET_MODE (op));
01100 }
01101 else
01102 {
01103 res = iv_get_reaching_def (insn, op, &def);
01104 if (res == GRD_INVALID)
01105 {
01106 if (dump_file)
01107 fprintf (dump_file, " not simple.\n");
01108 return false;
01109 }
01110 }
01111
01112 if (res == GRD_INVARIANT)
01113 {
01114 iv_constant (iv, op, VOIDmode);
01115
01116 if (dump_file)
01117 {
01118 fprintf (dump_file, " ");
01119 dump_iv_info (dump_file, iv);
01120 fprintf (dump_file, "\n");
01121 }
01122 return true;
01123 }
01124
01125 if (res == GRD_MAYBE_BIV)
01126 return iv_analyze_biv (op, iv);
01127
01128 return iv_analyze_def (def, iv);
01129 }
01130
01131
01132
01133 bool
01134 iv_analyze (rtx insn, rtx val, struct rtx_iv *iv)
01135 {
01136 rtx reg;
01137
01138
01139
01140
01141
01142 if (simple_reg_p (val))
01143 {
01144 if (GET_CODE (val) == SUBREG)
01145 reg = SUBREG_REG (val);
01146 else
01147 reg = val;
01148
01149 while (!df_find_use (df, insn, reg))
01150 insn = NEXT_INSN (insn);
01151 }
01152
01153 return iv_analyze_op (insn, val, iv);
01154 }
01155
01156
01157
01158 bool
01159 iv_analyze_result (rtx insn, rtx def, struct rtx_iv *iv)
01160 {
01161 struct df_ref *adef;
01162
01163 adef = df_find_def (df, insn, def);
01164 if (!adef)
01165 return false;
01166
01167 return iv_analyze_def (adef, iv);
01168 }
01169
01170
01171
01172
01173
01174 bool
01175 biv_p (rtx insn, rtx reg)
01176 {
01177 struct rtx_iv iv;
01178 struct df_ref *def, *last_def;
01179
01180 if (!simple_reg_p (reg))
01181 return false;
01182
01183 def = df_find_def (df, insn, reg);
01184 gcc_assert (def != NULL);
01185 if (!latch_dominating_def (reg, &last_def))
01186 return false;
01187 if (last_def != def)
01188 return false;
01189
01190 if (!iv_analyze_biv (reg, &iv))
01191 return false;
01192
01193 return iv.step != const0_rtx;
01194 }
01195
01196
01197
01198 rtx
01199 get_iv_value (struct rtx_iv *iv, rtx iteration)
01200 {
01201 rtx val;
01202
01203
01204
01205 gcc_assert (!iv->first_special);
01206
01207 if (iv->step != const0_rtx && iteration != const0_rtx)
01208 val = simplify_gen_binary (PLUS, iv->extend_mode, iv->base,
01209 simplify_gen_binary (MULT, iv->extend_mode,
01210 iv->step, iteration));
01211 else
01212 val = iv->base;
01213
01214 if (iv->extend_mode == iv->mode)
01215 return val;
01216
01217 val = lowpart_subreg (iv->mode, val, iv->extend_mode);
01218
01219 if (iv->extend == UNKNOWN)
01220 return val;
01221
01222 val = simplify_gen_unary (iv->extend, iv->extend_mode, val, iv->mode);
01223 val = simplify_gen_binary (PLUS, iv->extend_mode, iv->delta,
01224 simplify_gen_binary (MULT, iv->extend_mode,
01225 iv->mult, val));
01226
01227 return val;
01228 }
01229
01230
01231
01232 void
01233 iv_analysis_done (void)
01234 {
01235 if (df)
01236 {
01237 clear_iv_info ();
01238 df_finish (df);
01239 df = NULL;
01240 htab_delete (bivs);
01241 bivs = NULL;
01242 }
01243 }
01244
01245
01246
01247 static unsigned HOST_WIDEST_INT
01248 inverse (unsigned HOST_WIDEST_INT x, int mod)
01249 {
01250 unsigned HOST_WIDEST_INT mask =
01251 ((unsigned HOST_WIDEST_INT) 1 << (mod - 1) << 1) - 1;
01252 unsigned HOST_WIDEST_INT rslt = 1;
01253 int i;
01254
01255 for (i = 0; i < mod - 1; i++)
01256 {
01257 rslt = (rslt * x) & mask;
01258 x = (x * x) & mask;
01259 }
01260
01261 return rslt;
01262 }
01263
01264
01265
01266 static unsigned HOST_WIDEST_INT
01267 determine_max_iter (struct niter_desc *desc)
01268 {
01269 rtx niter = desc->niter_expr;
01270 rtx mmin, mmax, left, right;
01271 unsigned HOST_WIDEST_INT nmax, inc;
01272
01273 if (GET_CODE (niter) == AND
01274 && GET_CODE (XEXP (niter, 0)) == CONST_INT)
01275 {
01276 nmax = INTVAL (XEXP (niter, 0));
01277 if (!(nmax & (nmax + 1)))
01278 {
01279 desc->niter_max = nmax;
01280 return nmax;
01281 }
01282 }
01283
01284 get_mode_bounds (desc->mode, desc->signed_p, desc->mode, &mmin, &mmax);
01285 nmax = INTVAL (mmax) - INTVAL (mmin);
01286
01287 if (GET_CODE (niter) == UDIV)
01288 {
01289 if (GET_CODE (XEXP (niter, 1)) != CONST_INT)
01290 {
01291 desc->niter_max = nmax;
01292 return nmax;
01293 }
01294 inc = INTVAL (XEXP (niter, 1));
01295 niter = XEXP (niter, 0);
01296 }
01297 else
01298 inc = 1;
01299
01300 if (GET_CODE (niter) == PLUS)
01301 {
01302 left = XEXP (niter, 0);
01303 right = XEXP (niter, 0);
01304
01305 if (GET_CODE (right) == CONST_INT)
01306 right = GEN_INT (-INTVAL (right));
01307 }
01308 else if (GET_CODE (niter) == MINUS)
01309 {
01310 left = XEXP (niter, 0);
01311 right = XEXP (niter, 0);
01312 }
01313 else
01314 {
01315 left = niter;
01316 right = mmin;
01317 }
01318
01319 if (GET_CODE (left) == CONST_INT)
01320 mmax = left;
01321 if (GET_CODE (right) == CONST_INT)
01322 mmin = right;
01323 nmax = INTVAL (mmax) - INTVAL (mmin);
01324
01325 desc->niter_max = nmax / inc;
01326 return nmax / inc;
01327 }
01328
01329
01330
01331 static int
01332 altered_reg_used (rtx *reg, void *alt)
01333 {
01334 if (!REG_P (*reg))
01335 return 0;
01336
01337 return REGNO_REG_SET_P (alt, REGNO (*reg));
01338 }
01339
01340
01341
01342 static void
01343 mark_altered (rtx expr, rtx by ATTRIBUTE_UNUSED, void *alt)
01344 {
01345 if (GET_CODE (expr) == SUBREG)
01346 expr = SUBREG_REG (expr);
01347 if (!REG_P (expr))
01348 return;
01349
01350 SET_REGNO_REG_SET (alt, REGNO (expr));
01351 }
01352
01353
01354
01355 static bool
01356 simple_rhs_p (rtx rhs)
01357 {
01358 rtx op0, op1;
01359
01360 if (CONSTANT_P (rhs)
01361 || REG_P (rhs))
01362 return true;
01363
01364 switch (GET_CODE (rhs))
01365 {
01366 case PLUS:
01367 case MINUS:
01368 op0 = XEXP (rhs, 0);
01369 op1 = XEXP (rhs, 1);
01370
01371 if (REG_P (op0) && CONSTANT_P (op1))
01372 return true;
01373 if (REG_P (op1) && CONSTANT_P (op0))
01374 return true;
01375
01376 return false;
01377
01378 default:
01379 return false;
01380 }
01381 }
01382
01383
01384
01385
01386 static void
01387 simplify_using_assignment (rtx insn, rtx *expr, regset altered)
01388 {
01389 rtx set = single_set (insn);
01390 rtx lhs = NULL_RTX, rhs;
01391 bool ret = false;
01392
01393 if (set)
01394 {
01395 lhs = SET_DEST (set);
01396 if (!REG_P (lhs)
01397 || altered_reg_used (&lhs, altered))
01398 ret = true;
01399 }
01400 else
01401 ret = true;
01402
01403 note_stores (PATTERN (insn), mark_altered, altered);
01404 if (CALL_P (insn))
01405 {
01406 int i;
01407
01408
01409 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
01410 if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
01411 SET_REGNO_REG_SET (altered, i);
01412 }
01413
01414 if (ret)
01415 return;
01416
01417 rhs = find_reg_equal_equiv_note (insn);
01418 if (rhs)
01419 rhs = XEXP (rhs, 0);
01420 else
01421 rhs = SET_SRC (set);
01422
01423 if (!simple_rhs_p (rhs))
01424 return;
01425
01426 if (for_each_rtx (&rhs, altered_reg_used, altered))
01427 return;
01428
01429 *expr = simplify_replace_rtx (*expr, lhs, rhs);
01430 }
01431
01432
01433
01434 static bool
01435 implies_p (rtx a, rtx b)
01436 {
01437 rtx op0, op1, opb0, opb1, r;
01438 enum machine_mode mode;
01439
01440 if (GET_CODE (a) == EQ)
01441 {
01442 op0 = XEXP (a, 0);
01443 op1 = XEXP (a, 1);
01444
01445 if (REG_P (op0))
01446 {
01447 r = simplify_replace_rtx (b, op0, op1);
01448 if (r == const_true_rtx)
01449 return true;
01450 }
01451
01452 if (REG_P (op1))
01453 {
01454 r = simplify_replace_rtx (b, op1, op0);
01455 if (r == const_true_rtx)
01456 return true;
01457 }
01458 }
01459
01460
01461 if ((GET_CODE (a) == GT || GET_CODE (a) == LT)
01462 && (GET_CODE (b) == GE || GET_CODE (b) == LE))
01463 {
01464 op0 = XEXP (a, 0);
01465 op1 = XEXP (a, 1);
01466 opb0 = XEXP (b, 0);
01467 opb1 = XEXP (b, 1);
01468
01469 if (GET_CODE (a) == GT)
01470 {
01471 r = op0;
01472 op0 = op1;
01473 op1 = r;
01474 }
01475
01476 if (GET_CODE (b) == GE)
01477 {
01478 r = opb0;
01479 opb0 = opb1;
01480 opb1 = r;
01481 }
01482
01483 mode = GET_MODE (op0);
01484 if (mode != GET_MODE (opb0))
01485 mode = VOIDmode;
01486 else if (mode == VOIDmode)
01487 {
01488 mode = GET_MODE (op1);
01489 if (mode != GET_MODE (opb1))
01490 mode = VOIDmode;
01491 }
01492
01493 if (mode != VOIDmode
01494 && rtx_equal_p (op1, opb1)
01495 && simplify_gen_binary (MINUS, mode, opb0, op0) == const1_rtx)
01496 return true;
01497 }
01498
01499 return false;
01500 }
01501
01502
01503
01504
01505
01506
01507
01508
01509 rtx
01510 canon_condition (rtx cond)
01511 {
01512 rtx tem;
01513 rtx op0, op1;
01514 enum rtx_code code;
01515 enum machine_mode mode;
01516
01517 code = GET_CODE (cond);
01518 op0 = XEXP (cond, 0);
01519 op1 = XEXP (cond, 1);
01520
01521 if (swap_commutative_operands_p (op0, op1))
01522 {
01523 code = swap_condition (code);
01524 tem = op0;
01525 op0 = op1;
01526 op1 = tem;
01527 }
01528
01529 mode = GET_MODE (op0);
01530 if (mode == VOIDmode)
01531 mode = GET_MODE (op1);
01532 gcc_assert (mode != VOIDmode);
01533
01534 if (GET_CODE (op1) == CONST_INT
01535 && GET_MODE_CLASS (mode) != MODE_CC
01536 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
01537 {
01538 HOST_WIDE_INT const_val = INTVAL (op1);
01539 unsigned HOST_WIDE_INT uconst_val = const_val;
01540 unsigned HOST_WIDE_INT max_val
01541 = (unsigned HOST_WIDE_INT) GET_MODE_MASK (mode);
01542
01543 switch (code)
01544 {
01545 case LE:
01546 if ((unsigned HOST_WIDE_INT) const_val != max_val >> 1)
01547 code = LT, op1 = gen_int_mode (const_val + 1, GET_MODE (op0));
01548 break;
01549
01550
01551
01552 case GE:
01553 if ((HOST_WIDE_INT) (const_val & max_val)
01554 != (((HOST_WIDE_INT) 1
01555 << (GET_MODE_BITSIZE (GET_MODE (op0)) - 1))))
01556 code = GT, op1 = gen_int_mode (const_val - 1, mode);
01557 break;
01558
01559 case LEU:
01560 if (uconst_val < max_val)
01561 code = LTU, op1 = gen_int_mode (uconst_val + 1, mode);
01562 break;
01563
01564 case GEU:
01565 if (uconst_val != 0)
01566 code = GTU, op1 = gen_int_mode (uconst_val - 1, mode);
01567 break;
01568
01569 default:
01570 break;
01571 }
01572 }
01573
01574 if (op0 != XEXP (cond, 0)
01575 || op1 != XEXP (cond, 1)
01576 || code != GET_CODE (cond)
01577 || GET_MODE (cond) != SImode)
01578 cond = gen_rtx_fmt_ee (code, SImode, op0, op1);
01579
01580 return cond;
01581 }
01582
01583
01584
01585
01586 void
01587 simplify_using_condition (rtx cond, rtx *expr, regset altered)
01588 {
01589 rtx rev, reve, exp = *expr;
01590
01591 if (!COMPARISON_P (exp))
01592 return;
01593
01594
01595
01596 if (altered
01597 && for_each_rtx (&cond, altered_reg_used, altered))
01598 return;
01599
01600 rev = reversed_condition (cond);
01601 reve = reversed_condition (exp);
01602
01603 cond = canon_condition (cond);
01604 exp = canon_condition (exp);
01605 if (rev)
01606 rev = canon_condition (rev);
01607 if (reve)
01608 reve = canon_condition (reve);
01609
01610 if (rtx_equal_p (exp, cond))
01611 {
01612 *expr = const_true_rtx;
01613 return;
01614 }
01615
01616
01617 if (rev && rtx_equal_p (exp, rev))
01618 {
01619 *expr = const0_rtx;
01620 return;
01621 }
01622
01623 if (implies_p (cond, exp))
01624 {
01625 *expr = const_true_rtx;
01626 return;
01627 }
01628
01629 if (reve && implies_p (cond, reve))
01630 {
01631 *expr = const0_rtx;
01632 return;
01633 }
01634
01635
01636
01637 if (rev && implies_p (exp, rev))
01638 {
01639 *expr = const0_rtx;
01640 return;
01641 }
01642
01643
01644 if (rev && reve && implies_p (reve, rev))
01645 {
01646 *expr = const_true_rtx;
01647 return;
01648 }
01649
01650
01651
01652 return;
01653 }
01654
01655
01656
01657
01658 static void
01659 eliminate_implied_condition (enum rtx_code op, rtx a, rtx *b)
01660 {
01661 switch (op)
01662 {
01663 case AND:
01664
01665 if (implies_p (a, *b))
01666 *b = const_true_rtx;
01667 break;
01668
01669 case IOR:
01670
01671 if (implies_p (*b, a))
01672 *b = const0_rtx;
01673 break;
01674
01675 default:
01676 gcc_unreachable ();
01677 }
01678 }
01679
01680
01681
01682
01683 static void
01684 eliminate_implied_conditions (enum rtx_code op, rtx *head, rtx tail)
01685 {
01686 rtx elt;
01687
01688 for (elt = tail; elt; elt = XEXP (elt, 1))
01689 eliminate_implied_condition (op, *head, &XEXP (elt, 0));
01690 for (elt = tail; elt; elt = XEXP (elt, 1))
01691 eliminate_implied_condition (op, XEXP (elt, 0), head);
01692 }
01693
01694
01695
01696
01697 static void
01698 simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr)
01699 {
01700 rtx head, tail, insn;
01701 rtx neutral, aggr;
01702 regset altered;
01703 edge e;
01704
01705 if (!*expr)
01706 return;
01707
01708 if (CONSTANT_P (*expr))
01709 return;
01710
01711 if (GET_CODE (*expr) == EXPR_LIST)
01712 {
01713 head = XEXP (*expr, 0);
01714 tail = XEXP (*expr, 1);
01715
01716 eliminate_implied_conditions (op, &head, tail);
01717
01718 switch (op)
01719 {
01720 case AND:
01721 neutral = const_true_rtx;
01722 aggr = const0_rtx;
01723 break;
01724
01725 case IOR:
01726 neutral = const0_rtx;
01727 aggr = const_true_rtx;
01728 break;
01729
01730 default:
01731 gcc_unreachable ();
01732 }
01733
01734 simplify_using_initial_values (loop, UNKNOWN, &head);
01735 if (head == aggr)
01736 {
01737 XEXP (*expr, 0) = aggr;
01738 XEXP (*expr, 1) = NULL_RTX;
01739 return;
01740 }
01741 else if (head == neutral)
01742 {
01743 *expr = tail;
01744 simplify_using_initial_values (loop, op, expr);
01745 return;
01746 }
01747 simplify_using_initial_values (loop, op, &tail);
01748
01749 if (tail && XEXP (tail, 0) == aggr)
01750 {
01751 *expr = tail;
01752 return;
01753 }
01754
01755 XEXP (*expr, 0) = head;
01756 XEXP (*expr, 1) = tail;
01757 return;
01758 }
01759
01760 gcc_assert (op == UNKNOWN);
01761
01762 e = loop_preheader_edge (loop);
01763 if (e->src == ENTRY_BLOCK_PTR)
01764 return;
01765
01766 altered = ALLOC_REG_SET (®_obstack);
01767
01768 while (1)
01769 {
01770 insn = BB_END (e->src);
01771 if (any_condjump_p (insn))
01772 {
01773 rtx cond = get_condition (BB_END (e->src), NULL, false, true);
01774
01775 if (cond && (e->flags & EDGE_FALLTHRU))
01776 cond = reversed_condition (cond);
01777 if (cond)
01778 {
01779 simplify_using_condition (cond, expr, altered);
01780 if (CONSTANT_P (*expr))
01781 {
01782 FREE_REG_SET (altered);
01783 return;
01784 }
01785 }
01786 }
01787
01788 FOR_BB_INSNS_REVERSE (e->src, insn)
01789 {
01790 if (!INSN_P (insn))
01791 continue;
01792
01793 simplify_using_assignment (insn, expr, altered);
01794 if (CONSTANT_P (*expr))
01795 {
01796 FREE_REG_SET (altered);
01797 return;
01798 }
01799 }
01800
01801 if (!single_pred_p (e->src)
01802 || single_pred (e->src) == ENTRY_BLOCK_PTR)
01803 break;
01804 e = single_pred_edge (e->src);
01805 }
01806
01807 FREE_REG_SET (altered);
01808 }
01809
01810
01811
01812
01813
01814 static void
01815 shorten_into_mode (struct rtx_iv *iv, enum machine_mode mode,
01816 enum rtx_code cond, bool signed_p, struct niter_desc *desc)
01817 {
01818 rtx mmin, mmax, cond_over, cond_under;
01819
01820 get_mode_bounds (mode, signed_p, iv->extend_mode, &mmin, &mmax);
01821 cond_under = simplify_gen_relational (LT, SImode, iv->extend_mode,
01822 iv->base, mmin);
01823 cond_over = simplify_gen_relational (GT, SImode, iv->extend_mode,
01824 iv->base, mmax);
01825
01826 switch (cond)
01827 {
01828 case LE:
01829 case LT:
01830 case LEU:
01831 case LTU:
01832 if (cond_under != const0_rtx)
01833 desc->infinite =
01834 alloc_EXPR_LIST (0, cond_under, desc->infinite);
01835 if (cond_over != const0_rtx)
01836 desc->noloop_assumptions =
01837 alloc_EXPR_LIST (0, cond_over, desc->noloop_assumptions);
01838 break;
01839
01840 case GE:
01841 case GT:
01842 case GEU:
01843 case GTU:
01844 if (cond_over != const0_rtx)
01845 desc->infinite =
01846 alloc_EXPR_LIST (0, cond_over, desc->infinite);
01847 if (cond_under != const0_rtx)
01848 desc->noloop_assumptions =
01849 alloc_EXPR_LIST (0, cond_under, desc->noloop_assumptions);
01850 break;
01851
01852 case NE:
01853 if (cond_over != const0_rtx)
01854 desc->infinite =
01855 alloc_EXPR_LIST (0, cond_over, desc->infinite);
01856 if (cond_under != const0_rtx)
01857 desc->infinite =
01858 alloc_EXPR_LIST (0, cond_under, desc->infinite);
01859 break;
01860
01861 default:
01862 gcc_unreachable ();
01863 }
01864
01865 iv->mode = mode;
01866 iv->extend = signed_p ? SIGN_EXTEND : ZERO_EXTEND;
01867 }
01868
01869
01870
01871
01872
01873 static bool
01874 canonicalize_iv_subregs (struct rtx_iv *iv0, struct rtx_iv *iv1,
01875 enum rtx_code cond, struct niter_desc *desc)
01876 {
01877 enum machine_mode comp_mode;
01878 bool signed_p;
01879
01880
01881
01882 if (iv0->first_special || iv0->mult != const1_rtx || iv0->delta != const0_rtx)
01883 return false;
01884 if (iv1->first_special || iv1->mult != const1_rtx || iv1->delta != const0_rtx)
01885 return false;
01886
01887
01888 switch (cond)
01889 {
01890 case LE:
01891 case LT:
01892 if (iv0->extend == ZERO_EXTEND
01893 || iv1->extend == ZERO_EXTEND)
01894 return false;
01895 signed_p = true;
01896 break;
01897
01898 case LEU:
01899 case LTU:
01900 if (iv0->extend == SIGN_EXTEND
01901 || iv1->extend == SIGN_EXTEND)
01902 return false;
01903 signed_p = false;
01904 break;
01905
01906 case NE:
01907 if (iv0->extend != UNKNOWN
01908 && iv1->extend != UNKNOWN
01909 && iv0->extend != iv1->extend)
01910 return false;
01911
01912 signed_p = false;
01913 if (iv0->extend != UNKNOWN)
01914 signed_p = iv0->extend == SIGN_EXTEND;
01915 if (iv1->extend != UNKNOWN)
01916 signed_p = iv1->extend == SIGN_EXTEND;
01917 break;
01918
01919 default:
01920 gcc_unreachable ();
01921 }
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936 comp_mode = iv0->extend_mode;
01937 if (GET_MODE_BITSIZE (comp_mode) < GET_MODE_BITSIZE (iv1->extend_mode))
01938 comp_mode = iv1->extend_mode;
01939
01940 if (iv0->extend_mode != comp_mode)
01941 {
01942 if (iv0->mode != iv0->extend_mode
01943 || iv0->step != const0_rtx)
01944 return false;
01945
01946 iv0->base = simplify_gen_unary (signed_p ? SIGN_EXTEND : ZERO_EXTEND,
01947 comp_mode, iv0->base, iv0->mode);
01948 iv0->extend_mode = comp_mode;
01949 }
01950
01951 if (iv1->extend_mode != comp_mode)
01952 {
01953 if (iv1->mode != iv1->extend_mode
01954 || iv1->step != const0_rtx)
01955 return false;
01956
01957 iv1->base = simplify_gen_unary (signed_p ? SIGN_EXTEND : ZERO_EXTEND,
01958 comp_mode, iv1->base, iv1->mode);
01959 iv1->extend_mode = comp_mode;
01960 }
01961
01962
01963
01964
01965 if (iv0->mode == iv0->extend_mode
01966 && iv0->step == const0_rtx
01967 && iv0->mode != iv1->mode)
01968 shorten_into_mode (iv0, iv1->mode, cond, signed_p, desc);
01969
01970 if (iv1->mode == iv1->extend_mode
01971 && iv1->step == const0_rtx
01972 && iv0->mode != iv1->mode)
01973 shorten_into_mode (iv1, iv0->mode, swap_condition (cond), signed_p, desc);
01974
01975 if (iv0->mode != iv1->mode)
01976 return false;
01977
01978 desc->mode = iv0->mode;
01979 desc->signed_p = signed_p;
01980
01981 return true;
01982 }
01983
01984
01985
01986
01987
01988 static void
01989 iv_number_of_iterations (struct loop *loop, rtx insn, rtx condition,
01990 struct niter_desc *desc)
01991 {
01992 rtx op0, op1, delta, step, bound, may_xform, tmp, tmp0, tmp1;
01993 struct rtx_iv iv0, iv1, tmp_iv;
01994 rtx assumption, may_not_xform;
01995 enum rtx_code cond;
01996 enum machine_mode mode, comp_mode;
01997 rtx mmin, mmax, mode_mmin, mode_mmax;
01998 unsigned HOST_WIDEST_INT s, size, d, inv;
01999 HOST_WIDEST_INT up, down, inc, step_val;
02000 int was_sharp = false;
02001 rtx old_niter;
02002 bool step_is_pow2;
02003
02004
02005
02006
02007
02008
02009
02010 desc->assumptions = NULL_RTX;
02011 desc->noloop_assumptions = NULL_RTX;
02012 desc->infinite = NULL_RTX;
02013 desc->simple_p = true;
02014
02015 desc->const_iter = false;
02016 desc->niter_expr = NULL_RTX;
02017 desc->niter_max = 0;
02018
02019 cond = GET_CODE (condition);
02020 gcc_assert (COMPARISON_P (condition));
02021
02022 mode = GET_MODE (XEXP (condition, 0));
02023 if (mode == VOIDmode)
02024 mode = GET_MODE (XEXP (condition, 1));
02025
02026 gcc_assert (mode != VOIDmode);
02027
02028
02029 if (GET_MODE_CLASS (mode) != MODE_INT
02030 && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
02031 goto fail;
02032
02033 op0 = XEXP (condition, 0);
02034 if (!iv_analyze (insn, op0, &iv0))
02035 goto fail;
02036 if (iv0.extend_mode == VOIDmode)
02037 iv0.mode = iv0.extend_mode = mode;
02038
02039 op1 = XEXP (condition, 1);
02040 if (!iv_analyze (insn, op1, &iv1))
02041 goto fail;
02042 if (iv1.extend_mode == VOIDmode)
02043 iv1.mode = iv1.extend_mode = mode;
02044
02045 if (GET_MODE_BITSIZE (iv0.extend_mode) > HOST_BITS_PER_WIDE_INT
02046 || GET_MODE_BITSIZE (iv1.extend_mode) > HOST_BITS_PER_WIDE_INT)
02047 goto fail;
02048
02049
02050
02051 switch (cond)
02052 {
02053 case GE:
02054 case GT:
02055 case GEU:
02056 case GTU:
02057 tmp_iv = iv0; iv0 = iv1; iv1 = tmp_iv;
02058 cond = swap_condition (cond);
02059 break;
02060 case NE:
02061 case LE:
02062 case LEU:
02063 case LT:
02064 case LTU:
02065 break;
02066 default:
02067 goto fail;
02068 }
02069
02070
02071
02072
02073
02074
02075 if (!canonicalize_iv_subregs (&iv0, &iv1, cond, desc))
02076 goto fail;
02077
02078 comp_mode = iv0.extend_mode;
02079 mode = iv0.mode;
02080 size = GET_MODE_BITSIZE (mode);
02081 get_mode_bounds (mode, (cond == LE || cond == LT), comp_mode, &mmin, &mmax);
02082 mode_mmin = lowpart_subreg (mode, mmin, comp_mode);
02083 mode_mmax = lowpart_subreg (mode, mmax, comp_mode);
02084
02085 if (GET_CODE (iv0.step) != CONST_INT || GET_CODE (iv1.step) != CONST_INT)
02086 goto fail;
02087
02088
02089
02090
02091 if (iv0.step != const0_rtx && iv1.step != const0_rtx)
02092 {
02093 if (cond != NE)
02094 goto fail;
02095
02096 iv0.step = simplify_gen_binary (MINUS, comp_mode, iv0.step, iv1.step);
02097 iv1.step = const0_rtx;
02098 }
02099
02100
02101
02102 if (iv0.step == const0_rtx && iv1.step == const0_rtx)
02103 goto fail;
02104
02105 if (cond != NE)
02106 {
02107 if (iv0.step == const0_rtx)
02108 step_val = -INTVAL (iv1.step);
02109 else
02110 step_val = INTVAL (iv0.step);
02111
02112
02113 if (step_val < 0)
02114 goto fail;
02115
02116 step_is_pow2 = !(step_val & (step_val - 1));
02117 }
02118 else
02119 {
02120
02121
02122 step_is_pow2 = false;
02123 step_val = 0;
02124 }
02125
02126
02127
02128 switch (cond)
02129 {
02130 case LT:
02131 case LTU:
02132
02133
02134
02135
02136
02137
02138 if (iv0.step == const0_rtx)
02139 {
02140 tmp = lowpart_subreg (mode, iv0.base, comp_mode);
02141 assumption = simplify_gen_relational (EQ, SImode, mode, tmp,
02142 mode_mmax);
02143 if (assumption == const_true_rtx)
02144 goto zero_iter_simplify;
02145 iv0.base = simplify_gen_binary (PLUS, comp_mode,
02146 iv0.base, const1_rtx);
02147 }
02148 else
02149 {
02150 tmp = lowpart_subreg (mode, iv1.base, comp_mode);
02151 assumption = simplify_gen_relational (EQ, SImode, mode, tmp,
02152 mode_mmin);
02153 if (assumption == const_true_rtx)
02154 goto zero_iter_simplify;
02155 iv1.base = simplify_gen_binary (PLUS, comp_mode,
02156 iv1.base, constm1_rtx);
02157 }
02158
02159 if (assumption != const0_rtx)
02160 desc->noloop_assumptions =
02161 alloc_EXPR_LIST (0, assumption, desc->noloop_assumptions);
02162 cond = (cond == LT) ? LE : LEU;
02163
02164
02165
02166 was_sharp = true;
02167 break;
02168 default: ;
02169 }
02170
02171
02172 if (cond != NE)
02173 {
02174 if (iv0.step == const0_rtx)
02175 {
02176 tmp = lowpart_subreg (mode, iv0.base, comp_mode);
02177 if (rtx_equal_p (tmp, mode_mmin))
02178 {
02179 desc->infinite =
02180 alloc_EXPR_LIST (0, const_true_rtx, NULL_RTX);
02181
02182 goto zero_iter_simplify;
02183 }
02184 }
02185 else
02186 {
02187 tmp = lowpart_subreg (mode, iv1.base, comp_mode);
02188 if (rtx_equal_p (tmp, mode_mmax))
02189 {
02190 desc->infinite =
02191 alloc_EXPR_LIST (0, const_true_rtx, NULL_RTX);
02192
02193 goto zero_iter_simplify;
02194 }
02195 }
02196 }
02197
02198
02199
02200
02201
02202
02203
02204 if (cond != NE)
02205 {
02206 if (iv0.step == const0_rtx)
02207 step = simplify_gen_unary (NEG, comp_mode, iv1.step, comp_mode);
02208 else
02209 step = iv0.step;
02210 delta = simplify_gen_binary (MINUS, comp_mode, iv1.base, iv0.base);
02211 delta = lowpart_subreg (mode, delta, comp_mode);
02212 delta = simplify_gen_binary (UMOD, mode, delta, step);
02213 may_xform = const0_rtx;
02214 may_not_xform = const_true_rtx;
02215
02216 if (GET_CODE (delta) == CONST_INT)
02217 {
02218 if (was_sharp && INTVAL (delta) == INTVAL (step) - 1)
02219 {
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229 may_xform = const_true_rtx;
02230 }
02231 else if (iv0.step == const0_rtx)
02232 {
02233 bound = simplify_gen_binary (PLUS, comp_mode, mmin, step);
02234 bound = simplify_gen_binary (MINUS, comp_mode, bound, delta);
02235 bound = lowpart_subreg (mode, bound, comp_mode);
02236 tmp = lowpart_subreg (mode, iv0.base, comp_mode);
02237 may_xform = simplify_gen_relational (cond, SImode, mode,
02238 bound, tmp);
02239 may_not_xform = simplify_gen_relational (reverse_condition (cond),
02240 SImode, mode,
02241 bound, tmp);
02242 }
02243 else
02244 {
02245 bound = simplify_gen_binary (MINUS, comp_mode, mmax, step);
02246 bound = simplify_gen_binary (PLUS, comp_mode, bound, delta);
02247 bound = lowpart_subreg (mode, bound, comp_mode);
02248 tmp = lowpart_subreg (mode, iv1.base, comp_mode);
02249 may_xform = simplify_gen_relational (cond, SImode, mode,
02250 tmp, bound);
02251 may_not_xform = simplify_gen_relational (reverse_condition (cond),
02252 SImode, mode,
02253 tmp, bound);
02254 }
02255 }
02256
02257 if (may_xform != const0_rtx)
02258 {
02259
02260
02261
02262 if (may_xform != const_true_rtx)
02263 {
02264
02265
02266
02267 if (step_is_pow2)
02268 desc->infinite = alloc_EXPR_LIST (0, may_not_xform,
02269 desc->infinite);
02270 else
02271 desc->assumptions = alloc_EXPR_LIST (0, may_xform,
02272 desc->assumptions);
02273 }
02274
02275
02276
02277
02278 inc = INTVAL (iv0.step) - INTVAL (iv1.step);
02279 if (GET_CODE (iv1.base) == CONST_INT)
02280 up = INTVAL (iv1.base);
02281 else
02282 up = INTVAL (mode_mmax) - inc;
02283 down = INTVAL (GET_CODE (iv0.base) == CONST_INT
02284 ? iv0.base
02285 : mode_mmin);
02286 desc->niter_max = (up - down) / inc + 1;
02287
02288 if (iv0.step == const0_rtx)
02289 {
02290 iv0.base = simplify_gen_binary (PLUS, comp_mode, iv0.base, delta);
02291 iv0.base = simplify_gen_binary (MINUS, comp_mode, iv0.base, step);
02292 }
02293 else
02294 {
02295 iv1.base = simplify_gen_binary (MINUS, comp_mode, iv1.base, delta);
02296 iv1.base = simplify_gen_binary (PLUS, comp_mode, iv1.base, step);
02297 }
02298
02299 tmp0 = lowpart_subreg (mode, iv0.base, comp_mode);
02300 tmp1 = lowpart_subreg (mode, iv1.base, comp_mode);
02301 assumption = simplify_gen_relational (reverse_condition (cond),
02302 SImode, mode, tmp0, tmp1);
02303 if (assumption == const_true_rtx)
02304 goto zero_iter_simplify;
02305 else if (assumption != const0_rtx)
02306 desc->noloop_assumptions =
02307 alloc_EXPR_LIST (0, assumption, desc->noloop_assumptions);
02308 cond = NE;
02309 }
02310 }
02311
02312
02313 if (cond == NE)
02314 {
02315
02316
02317
02318
02319 iv1.base = simplify_gen_binary (MINUS, comp_mode, iv1.base, iv0.base);
02320 iv0.base = const0_rtx;
02321 iv0.step = simplify_gen_binary (MINUS, comp_mode, iv0.step, iv1.step);
02322 iv1.step = const0_rtx;
02323 if (INTVAL (iv0.step) < 0)
02324 {
02325 iv0.step = simplify_gen_unary (NEG, comp_mode, iv0.step, mode);
02326 iv1.base = simplify_gen_unary (NEG, comp_mode, iv1.base, mode);
02327 }
02328 iv0.step = lowpart_subreg (mode, iv0.step, comp_mode);
02329
02330
02331
02332
02333 s = INTVAL (iv0.step); d = 1;
02334 while (s % 2 != 1)
02335 {
02336 s /= 2;
02337 d *= 2;
02338 size--;
02339 }
02340 bound = GEN_INT (((unsigned HOST_WIDEST_INT) 1 << (size - 1 ) << 1) - 1);
02341
02342 tmp1 = lowpart_subreg (mode, iv1.base, comp_mode);
02343 tmp = simplify_gen_binary (UMOD, mode, tmp1, GEN_INT (d));
02344 assumption = simplify_gen_relational (NE, SImode, mode, tmp, const0_rtx);
02345 desc->infinite = alloc_EXPR_LIST (0, assumption, desc->infinite);
02346
02347 tmp = simplify_gen_binary (UDIV, mode, tmp1, GEN_INT (d));
02348 inv = inverse (s, size);
02349 tmp = simplify_gen_binary (MULT, mode, tmp, gen_int_mode (inv, mode));
02350 desc->niter_expr = simplify_gen_binary (AND, mode, tmp, bound);
02351 }
02352 else
02353 {
02354 if (iv1.step == const0_rtx)
02355
02356
02357
02358
02359
02360
02361 {
02362 step = iv0.step;
02363 tmp0 = lowpart_subreg (mode, iv0.base, comp_mode);
02364 tmp1 = lowpart_subreg (mode, iv1.base, comp_mode);
02365
02366 bound = simplify_gen_binary (MINUS, mode, mode_mmax,
02367 lowpart_subreg (mode, step,
02368 comp_mode));
02369 if (step_is_pow2)
02370 {
02371 rtx t0, t1;
02372
02373
02374
02375 assumption = simplify_gen_relational (reverse_condition (cond),
02376 SImode, mode,
02377 tmp1, bound);
02378
02379 t0 = simplify_gen_binary (UMOD, mode, copy_rtx (tmp0), step);
02380 t1 = simplify_gen_binary (UMOD, mode, copy_rtx (tmp1), step);
02381 tmp = simplify_gen_relational (cond, SImode, mode, t0, t1);
02382 assumption = simplify_gen_binary (AND, SImode, assumption, tmp);
02383 desc->infinite =
02384 alloc_EXPR_LIST (0, assumption, desc->infinite);
02385 }
02386 else
02387 {
02388 assumption = simplify_gen_relational (cond, SImode, mode,
02389 tmp1, bound);
02390 desc->assumptions =
02391 alloc_EXPR_LIST (0, assumption, desc->assumptions);
02392 }
02393
02394 tmp = simplify_gen_binary (PLUS, comp_mode, iv1.base, iv0.step);
02395 tmp = lowpart_subreg (mode, tmp, comp_mode);
02396 assumption = simplify_gen_relational (reverse_condition (cond),
02397 SImode, mode, tmp0, tmp);
02398
02399 delta = simplify_gen_binary (PLUS, mode, tmp1, step);
02400 delta = simplify_gen_binary (MINUS, mode, delta, tmp0);
02401 }
02402 else
02403 {
02404
02405
02406
02407 step = simplify_gen_unary (NEG, mode, iv1.step, mode);
02408 tmp0 = lowpart_subreg (mode, iv0.base, comp_mode);
02409 tmp1 = lowpart_subreg (mode, iv1.base, comp_mode);
02410
02411 bound = simplify_gen_binary (PLUS, mode, mode_mmin,
02412 lowpart_subreg (mode, step, comp_mode));
02413 if (step_is_pow2)
02414 {
02415 rtx t0, t1;
02416
02417
02418
02419 assumption = simplify_gen_relational (reverse_condition (cond),
02420 SImode, mode,
02421 bound, tmp0);
02422
02423 t0 = simplify_gen_binary (UMOD, mode, copy_rtx (tmp0), step);
02424 t1 = simplify_gen_binary (UMOD, mode, copy_rtx (tmp1), step);
02425 tmp = simplify_gen_relational (cond, SImode, mode, t0, t1);
02426 assumption = simplify_gen_binary (AND, SImode, assumption, tmp);
02427 desc->infinite =
02428 alloc_EXPR_LIST (0, assumption, desc->infinite);
02429 }
02430 else
02431 {
02432 assumption = simplify_gen_relational (cond, SImode, mode,
02433 bound, tmp0);
02434 desc->assumptions =
02435 alloc_EXPR_LIST (0, assumption, desc->assumptions);
02436 }
02437
02438 tmp = simplify_gen_binary (PLUS, comp_mode, iv0.base, iv1.step);
02439 tmp = lowpart_subreg (mode, tmp, comp_mode);
02440 assumption = simplify_gen_relational (reverse_condition (cond),
02441 SImode, mode,
02442 tmp, tmp1);
02443 delta = simplify_gen_binary (MINUS, mode, tmp0, step);
02444 delta = simplify_gen_binary (MINUS, mode, tmp1, delta);
02445 }
02446 if (assumption == const_true_rtx)
02447 goto zero_iter_simplify;
02448 else if (assumption != const0_rtx)
02449 desc->noloop_assumptions =
02450 alloc_EXPR_LIST (0, assumption, desc->noloop_assumptions);
02451 delta = simplify_gen_binary (UDIV, mode, delta, step);
02452 desc->niter_expr = delta;
02453 }
02454
02455 old_niter = desc->niter_expr;
02456
02457 simplify_using_initial_values (loop, AND, &desc->assumptions);
02458 if (desc->assumptions
02459 && XEXP (desc->assumptions, 0) == const0_rtx)
02460 goto fail;
02461 simplify_using_initial_values (loop, IOR, &desc->noloop_assumptions);
02462 simplify_using_initial_values (loop, IOR, &desc->infinite);
02463 simplify_using_initial_values (loop, UNKNOWN, &desc->niter_expr);
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477
02478
02479
02480 simplify_using_initial_values (loop, AND, &desc->assumptions);
02481 if (desc->assumptions
02482 && XEXP (desc->assumptions, 0) == const0_rtx)
02483 goto fail;
02484 simplify_using_initial_values (loop, IOR, &desc->noloop_assumptions);
02485 simplify_using_initial_values (loop, IOR, &desc->infinite);
02486 simplify_using_initial_values (loop, UNKNOWN, &desc->niter_expr);
02487
02488 if (desc->noloop_assumptions
02489 && XEXP (desc->noloop_assumptions, 0) == const_true_rtx)
02490 goto zero_iter;
02491
02492 if (GET_CODE (desc->niter_expr) == CONST_INT)
02493 {
02494 unsigned HOST_WIDEST_INT val = INTVAL (desc->niter_expr);
02495
02496 desc->const_iter = true;
02497 desc->niter_max = desc->niter = val & GET_MODE_MASK (desc->mode);
02498 }
02499 else
02500 {
02501 if (!desc->niter_max)
02502 desc->niter_max = determine_max_iter (desc);
02503
02504
02505
02506
02507
02508
02509
02510 desc->niter_expr = old_niter;
02511 }
02512
02513 return;
02514
02515 zero_iter_simplify:
02516
02517 simplify_using_initial_values (loop, AND, &desc->assumptions);
02518 if (desc->assumptions
02519 && XEXP (desc->assumptions, 0) == const0_rtx)
02520 goto fail;
02521 simplify_using_initial_values (loop, IOR, &desc->infinite);
02522
02523
02524 zero_iter:
02525 desc->const_iter = true;
02526 desc->niter = 0;
02527 desc->niter_max = 0;
02528 desc->noloop_assumptions = NULL_RTX;
02529 desc->niter_expr = const0_rtx;
02530 return;
02531
02532 fail:
02533 desc->simple_p = false;
02534 return;
02535 }
02536
02537
02538
02539
02540 static void
02541 check_simple_exit (struct loop *loop, edge e, struct niter_desc *desc)
02542 {
02543 basic_block exit_bb;
02544 rtx condition, at;
02545 edge ein;
02546
02547 exit_bb = e->src;
02548 desc->simple_p = false;
02549
02550
02551 if (exit_bb->loop_father != loop)
02552 return;
02553
02554
02555 if (!dominated_by_p (CDI_DOMINATORS, loop->latch, exit_bb))
02556 return;
02557
02558
02559 if (!any_condjump_p (BB_END (exit_bb)))
02560 return;
02561
02562 ein = EDGE_SUCC (exit_bb, 0);
02563 if (ein == e)
02564 ein = EDGE_SUCC (exit_bb, 1);
02565
02566 desc->out_edge = e;
02567 desc->in_edge = ein;
02568
02569
02570 if (!(condition = get_condition (BB_END (ein->src), &at, false, false)))
02571 return;
02572
02573 if (ein->flags & EDGE_FALLTHRU)
02574 {
02575 condition = reversed_condition (condition);
02576 if (!condition)
02577 return;
02578 }
02579
02580
02581
02582 iv_number_of_iterations (loop, at, condition, desc);
02583 }
02584
02585
02586
02587 void
02588 find_simple_exit (struct loop *loop, struct niter_desc *desc)
02589 {
02590 unsigned i;
02591 basic_block *body;
02592 edge e;
02593 struct niter_desc act;
02594 bool any = false;
02595 edge_iterator ei;
02596
02597 desc->simple_p = false;
02598 body = get_loop_body (loop);
02599
02600 for (i = 0; i < loop->num_nodes; i++)
02601 {
02602 FOR_EACH_EDGE (e, ei, body[i]->succs)
02603 {
02604 if (flow_bb_inside_loop_p (loop, e->dest))
02605 continue;
02606
02607 check_simple_exit (loop, e, &act);
02608 if (!act.simple_p)
02609 continue;
02610
02611 if (!any)
02612 any = true;
02613 else
02614 {
02615
02616 if (!act.const_iter
02617 || (desc->const_iter && act.niter >= desc->niter))
02618 continue;
02619
02620
02621
02622 if (act.infinite && !desc->infinite)
02623 continue;
02624 }
02625
02626 *desc = act;
02627 }
02628 }
02629
02630 if (dump_file)
02631 {
02632 if (desc->simple_p)
02633 {
02634 fprintf (dump_file, "Loop %d is simple:\n", loop->num);
02635 fprintf (dump_file, " simple exit %d -> %d\n",
02636 desc->out_edge->src->index,
02637 desc->out_edge->dest->index);
02638 if (desc->assumptions)
02639 {
02640 fprintf (dump_file, " assumptions: ");
02641 print_rtl (dump_file, desc->assumptions);
02642 fprintf (dump_file, "\n");
02643 }
02644 if (desc->noloop_assumptions)
02645 {
02646 fprintf (dump_file, " does not roll if: ");
02647 print_rtl (dump_file, desc->noloop_assumptions);
02648 fprintf (dump_file, "\n");
02649 }
02650 if (desc->infinite)
02651 {
02652 fprintf (dump_file, " infinite if: ");
02653 print_rtl (dump_file, desc->infinite);
02654 fprintf (dump_file, "\n");
02655 }
02656
02657 fprintf (dump_file, " number of iterations: ");
02658 print_rtl (dump_file, desc->niter_expr);
02659 fprintf (dump_file, "\n");
02660
02661 fprintf (dump_file, " upper bound: ");
02662 fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC, desc->niter_max);
02663 fprintf (dump_file, "\n");
02664 }
02665 else
02666 fprintf (dump_file, "Loop %d is not simple.\n", loop->num);
02667 }
02668
02669 free (body);
02670 }
02671
02672
02673
02674
02675 struct niter_desc *
02676 get_simple_loop_desc (struct loop *loop)
02677 {
02678 struct niter_desc *desc = simple_loop_desc (loop);
02679
02680 if (desc)
02681 return desc;
02682
02683 desc = XNEW (struct niter_desc);
02684 iv_analysis_loop_init (loop);
02685 find_simple_exit (loop, desc);
02686 loop->aux = desc;
02687
02688 if (desc->simple_p && (desc->assumptions || desc->infinite))
02689 {
02690 const char *wording;
02691
02692
02693
02694 if (!flag_tree_loop_optimize && warn_unsafe_loop_optimizations)
02695 {
02696 if (desc->infinite)
02697 {
02698 wording =
02699 flag_unsafe_loop_optimizations
02700 ? N_("assuming that the loop is not infinite")
02701 : N_("cannot optimize possibly infinite loops");
02702 warning (OPT_Wunsafe_loop_optimizations, "%s",
02703 gettext (wording));
02704 }
02705 if (desc->assumptions)
02706 {
02707 wording =
02708 flag_unsafe_loop_optimizations
02709 ? N_("assuming that the loop counter does not overflow")
02710 : N_("cannot optimize loop, the loop counter may overflow");
02711 warning (OPT_Wunsafe_loop_optimizations, "%s",
02712 gettext (wording));
02713 }
02714 }
02715
02716 if (flag_unsafe_loop_optimizations)
02717 {
02718 desc->assumptions = NULL_RTX;
02719 desc->infinite = NULL_RTX;
02720 }
02721 }
02722
02723 return desc;
02724 }
02725
02726
02727
02728 void
02729 free_simple_loop_desc (struct loop *loop)
02730 {
02731 struct niter_desc *desc = simple_loop_desc (loop);
02732
02733 if (!desc)
02734 return;
02735
02736 free (desc);
02737 loop->aux = NULL;
02738 }