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 #include "config.h"
00050 #include "system.h"
00051 #include "flags.h"
00052 #ifdef SGI_MONGOOSE
00053
00054 #include "rtl.h"
00055 #endif
00056 #include "tree.h"
00057 #include "real.h"
00058 #ifndef SGI_MONGOOSE
00059 #include "rtl.h"
00060 #endif
00061 #include "expr.h"
00062 #include "tm_p.h"
00063 #include "toplev.h"
00064 #include "ggc.h"
00065 #include "hashtab.h"
00066 #include "langhooks.h"
00067 #include "md5.h"
00068
00069 static void encode PARAMS ((HOST_WIDE_INT *,
00070 unsigned HOST_WIDE_INT,
00071 HOST_WIDE_INT));
00072 static void decode PARAMS ((HOST_WIDE_INT *,
00073 unsigned HOST_WIDE_INT *,
00074 HOST_WIDE_INT *));
00075 static tree negate_expr PARAMS ((tree));
00076 static tree split_tree PARAMS ((tree, enum tree_code, tree *, tree *,
00077 tree *, int));
00078 static tree associate_trees PARAMS ((tree, tree, enum tree_code, tree));
00079 static tree int_const_binop PARAMS ((enum tree_code, tree, tree, int));
00080 static tree const_binop PARAMS ((enum tree_code, tree, tree, int));
00081 static hashval_t size_htab_hash PARAMS ((const void *));
00082 static int size_htab_eq PARAMS ((const void *, const void *));
00083 static tree fold_convert PARAMS ((tree, tree));
00084 static enum tree_code invert_tree_comparison PARAMS ((enum tree_code));
00085 static enum tree_code swap_tree_comparison PARAMS ((enum tree_code));
00086 static int comparison_to_compcode PARAMS ((enum tree_code));
00087 static enum tree_code compcode_to_comparison PARAMS ((int));
00088 static int truth_value_p PARAMS ((enum tree_code));
00089 static int operand_equal_for_comparison_p PARAMS ((tree, tree, tree));
00090 static int twoval_comparison_p PARAMS ((tree, tree *, tree *, int *));
00091 static tree eval_subst PARAMS ((tree, tree, tree, tree, tree));
00092 static tree omit_one_operand PARAMS ((tree, tree, tree));
00093 static tree pedantic_omit_one_operand PARAMS ((tree, tree, tree));
00094 static tree distribute_bit_expr PARAMS ((enum tree_code, tree, tree, tree));
00095 static tree make_bit_field_ref PARAMS ((tree, tree, int, int, int));
00096 static tree optimize_bit_field_compare PARAMS ((enum tree_code, tree,
00097 tree, tree));
00098 static tree decode_field_reference PARAMS ((tree, HOST_WIDE_INT *,
00099 HOST_WIDE_INT *,
00100 enum machine_mode *, int *,
00101 int *, tree *, tree *));
00102 static int all_ones_mask_p PARAMS ((tree, int));
00103 static tree sign_bit_p PARAMS ((tree, tree));
00104 static int simple_operand_p PARAMS ((tree));
00105 static tree range_binop PARAMS ((enum tree_code, tree, tree, int,
00106 tree, int));
00107 static tree make_range PARAMS ((tree, int *, tree *, tree *));
00108 static tree build_range_check PARAMS ((tree, tree, int, tree, tree));
00109 static int merge_ranges PARAMS ((int *, tree *, tree *, int, tree, tree,
00110 int, tree, tree));
00111 static tree fold_range_test PARAMS ((tree));
00112 static tree unextend PARAMS ((tree, int, int, tree));
00113 static tree fold_truthop PARAMS ((enum tree_code, tree, tree, tree));
00114 static tree optimize_minmax_comparison PARAMS ((tree));
00115 static tree extract_muldiv PARAMS ((tree, tree, enum tree_code, tree));
00116 static tree extract_muldiv_1 PARAMS ((tree, tree, enum tree_code, tree));
00117 static tree strip_compound_expr PARAMS ((tree, tree));
00118 static int multiple_of_p PARAMS ((tree, tree, tree));
00119 static tree constant_boolean_node PARAMS ((int, tree));
00120 static int count_cond PARAMS ((tree, int));
00121 static tree fold_binary_op_with_conditional_arg
00122 PARAMS ((enum tree_code, tree, tree, tree, int));
00123 static bool fold_real_zero_addition_p PARAMS ((tree, tree, int));
00124
00125
00126
00127
00128 #define COMPCODE_FALSE 0
00129 #define COMPCODE_LT 1
00130 #define COMPCODE_EQ 2
00131 #define COMPCODE_LE 3
00132 #define COMPCODE_GT 4
00133 #define COMPCODE_NE 5
00134 #define COMPCODE_GE 6
00135 #define COMPCODE_TRUE 7
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 #define OVERFLOW_SUM_SIGN(a, b, sum) ((~((a) ^ (b)) & ((a) ^ (sum))) < 0)
00146
00147
00148
00149
00150
00151
00152 #define LOWPART(x) \
00153 ((x) & (((unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)) - 1))
00154 #define HIGHPART(x) \
00155 ((unsigned HOST_WIDE_INT) (x) >> HOST_BITS_PER_WIDE_INT / 2)
00156 #define BASE ((unsigned HOST_WIDE_INT) 1 << HOST_BITS_PER_WIDE_INT / 2)
00157
00158
00159
00160
00161
00162 static void
00163 encode (words, low, hi)
00164 HOST_WIDE_INT *words;
00165 unsigned HOST_WIDE_INT low;
00166 HOST_WIDE_INT hi;
00167 {
00168 words[0] = LOWPART (low);
00169 words[1] = HIGHPART (low);
00170 words[2] = LOWPART (hi);
00171 words[3] = HIGHPART (hi);
00172 }
00173
00174
00175
00176
00177
00178 static void
00179 decode (words, low, hi)
00180 HOST_WIDE_INT *words;
00181 unsigned HOST_WIDE_INT *low;
00182 HOST_WIDE_INT *hi;
00183 {
00184 *low = words[0] + words[1] * BASE;
00185 *hi = words[2] + words[3] * BASE;
00186 }
00187
00188
00189
00190
00191
00192
00193
00194
00195 int
00196 force_fit_type (t, overflow)
00197 tree t;
00198 int overflow;
00199 {
00200 unsigned HOST_WIDE_INT low;
00201 HOST_WIDE_INT high;
00202 unsigned int prec;
00203
00204 if (TREE_CODE (t) == REAL_CST)
00205 {
00206
00207
00208 return overflow;
00209 }
00210
00211 else if (TREE_CODE (t) != INTEGER_CST)
00212 return overflow;
00213
00214 low = TREE_INT_CST_LOW (t);
00215 high = TREE_INT_CST_HIGH (t);
00216
00217 if (POINTER_TYPE_P (TREE_TYPE (t)))
00218 prec = POINTER_SIZE;
00219 else
00220 prec = TYPE_PRECISION (TREE_TYPE (t));
00221
00222
00223
00224 if (prec == 2 * HOST_BITS_PER_WIDE_INT)
00225 ;
00226 else if (prec > HOST_BITS_PER_WIDE_INT)
00227 TREE_INT_CST_HIGH (t)
00228 &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
00229 else
00230 {
00231 TREE_INT_CST_HIGH (t) = 0;
00232 if (prec < HOST_BITS_PER_WIDE_INT)
00233 TREE_INT_CST_LOW (t) &= ~((unsigned HOST_WIDE_INT) (-1) << prec);
00234 }
00235
00236
00237
00238 if (TREE_UNSIGNED (TREE_TYPE (t))
00239 && ! (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
00240 && TYPE_IS_SIZETYPE (TREE_TYPE (t))))
00241 return overflow;
00242
00243
00244 if (prec != 2 * HOST_BITS_PER_WIDE_INT
00245 && (prec > HOST_BITS_PER_WIDE_INT
00246 ? 0 != (TREE_INT_CST_HIGH (t)
00247 & ((HOST_WIDE_INT) 1
00248 << (prec - HOST_BITS_PER_WIDE_INT - 1)))
00249 : 0 != (TREE_INT_CST_LOW (t)
00250 & ((unsigned HOST_WIDE_INT) 1 << (prec - 1)))))
00251 {
00252
00253
00254 if (prec > HOST_BITS_PER_WIDE_INT)
00255 TREE_INT_CST_HIGH (t)
00256 |= ((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
00257 else
00258 {
00259 TREE_INT_CST_HIGH (t) = -1;
00260 if (prec < HOST_BITS_PER_WIDE_INT)
00261 TREE_INT_CST_LOW (t) |= ((unsigned HOST_WIDE_INT) (-1) << prec);
00262 }
00263 }
00264
00265
00266 return
00267 ((overflow | (low ^ TREE_INT_CST_LOW (t)) | (high ^ TREE_INT_CST_HIGH (t)))
00268 != 0);
00269 }
00270
00271
00272
00273
00274
00275
00276 int
00277 add_double (l1, h1, l2, h2, lv, hv)
00278 unsigned HOST_WIDE_INT l1, l2;
00279 HOST_WIDE_INT h1, h2;
00280 unsigned HOST_WIDE_INT *lv;
00281 HOST_WIDE_INT *hv;
00282 {
00283 unsigned HOST_WIDE_INT l;
00284 HOST_WIDE_INT h;
00285
00286 l = l1 + l2;
00287 h = h1 + h2 + (l < l1);
00288
00289 *lv = l;
00290 *hv = h;
00291 return OVERFLOW_SUM_SIGN (h1, h2, h);
00292 }
00293
00294
00295
00296
00297
00298
00299 int
00300 neg_double (l1, h1, lv, hv)
00301 unsigned HOST_WIDE_INT l1;
00302 HOST_WIDE_INT h1;
00303 unsigned HOST_WIDE_INT *lv;
00304 HOST_WIDE_INT *hv;
00305 {
00306 if (l1 == 0)
00307 {
00308 *lv = 0;
00309 *hv = - h1;
00310 return (*hv & h1) < 0;
00311 }
00312 else
00313 {
00314 *lv = -l1;
00315 *hv = ~h1;
00316 return 0;
00317 }
00318 }
00319
00320
00321
00322
00323
00324
00325
00326 int
00327 mul_double (l1, h1, l2, h2, lv, hv)
00328 unsigned HOST_WIDE_INT l1, l2;
00329 HOST_WIDE_INT h1, h2;
00330 unsigned HOST_WIDE_INT *lv;
00331 HOST_WIDE_INT *hv;
00332 {
00333 HOST_WIDE_INT arg1[4];
00334 HOST_WIDE_INT arg2[4];
00335 HOST_WIDE_INT prod[4 * 2];
00336 unsigned HOST_WIDE_INT carry;
00337 int i, j, k;
00338 unsigned HOST_WIDE_INT toplow, neglow;
00339 HOST_WIDE_INT tophigh, neghigh;
00340
00341 encode (arg1, l1, h1);
00342 encode (arg2, l2, h2);
00343
00344 memset ((char *) prod, 0, sizeof prod);
00345
00346 for (i = 0; i < 4; i++)
00347 {
00348 carry = 0;
00349 for (j = 0; j < 4; j++)
00350 {
00351 k = i + j;
00352
00353 carry += arg1[i] * arg2[j];
00354
00355 carry += prod[k];
00356 prod[k] = LOWPART (carry);
00357 carry = HIGHPART (carry);
00358 }
00359 prod[i + 4] = carry;
00360 }
00361
00362 decode (prod, lv, hv);
00363
00364
00365
00366 decode (prod + 4, &toplow, &tophigh);
00367 if (h1 < 0)
00368 {
00369 neg_double (l2, h2, &neglow, &neghigh);
00370 add_double (neglow, neghigh, toplow, tophigh, &toplow, &tophigh);
00371 }
00372 if (h2 < 0)
00373 {
00374 neg_double (l1, h1, &neglow, &neghigh);
00375 add_double (neglow, neghigh, toplow, tophigh, &toplow, &tophigh);
00376 }
00377 return (*hv < 0 ? ~(toplow & tophigh) : toplow | tophigh) != 0;
00378 }
00379
00380
00381
00382
00383
00384
00385
00386 void
00387 lshift_double (l1, h1, count, prec, lv, hv, arith)
00388 unsigned HOST_WIDE_INT l1;
00389 HOST_WIDE_INT h1, count;
00390 unsigned int prec;
00391 unsigned HOST_WIDE_INT *lv;
00392 HOST_WIDE_INT *hv;
00393 int arith;
00394 {
00395 unsigned HOST_WIDE_INT signmask;
00396
00397 if (count < 0)
00398 {
00399 rshift_double (l1, h1, -count, prec, lv, hv, arith);
00400 return;
00401 }
00402
00403 #ifdef SHIFT_COUNT_TRUNCATED
00404 if (SHIFT_COUNT_TRUNCATED)
00405 count %= prec;
00406 #endif
00407
00408 if (count >= 2 * HOST_BITS_PER_WIDE_INT)
00409 {
00410
00411
00412 *hv = 0;
00413 *lv = 0;
00414 }
00415 else if (count >= HOST_BITS_PER_WIDE_INT)
00416 {
00417 *hv = l1 << (count - HOST_BITS_PER_WIDE_INT);
00418 *lv = 0;
00419 }
00420 else
00421 {
00422 *hv = (((unsigned HOST_WIDE_INT) h1 << count)
00423 | (l1 >> (HOST_BITS_PER_WIDE_INT - count - 1) >> 1));
00424 *lv = l1 << count;
00425 }
00426
00427
00428
00429 signmask = -((prec > HOST_BITS_PER_WIDE_INT
00430 ? ((unsigned HOST_WIDE_INT) *hv
00431 >> (prec - HOST_BITS_PER_WIDE_INT - 1))
00432 : (*lv >> (prec - 1))) & 1);
00433
00434 if (prec >= 2 * HOST_BITS_PER_WIDE_INT)
00435 ;
00436 else if (prec >= HOST_BITS_PER_WIDE_INT)
00437 {
00438 *hv &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
00439 *hv |= signmask << (prec - HOST_BITS_PER_WIDE_INT);
00440 }
00441 else
00442 {
00443 *hv = signmask;
00444 *lv &= ~((unsigned HOST_WIDE_INT) (-1) << prec);
00445 *lv |= signmask << prec;
00446 }
00447 }
00448
00449
00450
00451
00452
00453
00454 void
00455 rshift_double (l1, h1, count, prec, lv, hv, arith)
00456 unsigned HOST_WIDE_INT l1;
00457 HOST_WIDE_INT h1, count;
00458 unsigned int prec;
00459 unsigned HOST_WIDE_INT *lv;
00460 HOST_WIDE_INT *hv;
00461 int arith;
00462 {
00463 unsigned HOST_WIDE_INT signmask;
00464
00465 signmask = (arith
00466 ? -((unsigned HOST_WIDE_INT) h1 >> (HOST_BITS_PER_WIDE_INT - 1))
00467 : 0);
00468
00469 #ifdef SHIFT_COUNT_TRUNCATED
00470 if (SHIFT_COUNT_TRUNCATED)
00471 count %= prec;
00472 #endif
00473
00474 if (count >= 2 * HOST_BITS_PER_WIDE_INT)
00475 {
00476
00477
00478 *hv = 0;
00479 *lv = 0;
00480 }
00481 else if (count >= HOST_BITS_PER_WIDE_INT)
00482 {
00483 *hv = 0;
00484 *lv = (unsigned HOST_WIDE_INT) h1 >> (count - HOST_BITS_PER_WIDE_INT);
00485 }
00486 else
00487 {
00488 *hv = (unsigned HOST_WIDE_INT) h1 >> count;
00489 *lv = ((l1 >> count)
00490 | ((unsigned HOST_WIDE_INT) h1 << (HOST_BITS_PER_WIDE_INT - count - 1) << 1));
00491 }
00492
00493
00494
00495 if (count >= (HOST_WIDE_INT)prec)
00496 {
00497 *hv = signmask;
00498 *lv = signmask;
00499 }
00500 else if ((prec - count) >= 2 * HOST_BITS_PER_WIDE_INT)
00501 ;
00502 else if ((prec - count) >= HOST_BITS_PER_WIDE_INT)
00503 {
00504 *hv &= ~((HOST_WIDE_INT) (-1) << (prec - count - HOST_BITS_PER_WIDE_INT));
00505 *hv |= signmask << (prec - count - HOST_BITS_PER_WIDE_INT);
00506 }
00507 else
00508 {
00509 *hv = signmask;
00510 *lv &= ~((unsigned HOST_WIDE_INT) (-1) << (prec - count));
00511 *lv |= signmask << (prec - count);
00512 }
00513 }
00514
00515
00516
00517
00518
00519
00520 void
00521 lrotate_double (l1, h1, count, prec, lv, hv)
00522 unsigned HOST_WIDE_INT l1;
00523 HOST_WIDE_INT h1, count;
00524 unsigned int prec;
00525 unsigned HOST_WIDE_INT *lv;
00526 HOST_WIDE_INT *hv;
00527 {
00528 unsigned HOST_WIDE_INT s1l, s2l;
00529 HOST_WIDE_INT s1h, s2h;
00530
00531 count %= prec;
00532 if (count < 0)
00533 count += prec;
00534
00535 lshift_double (l1, h1, count, prec, &s1l, &s1h, 0);
00536 rshift_double (l1, h1, prec - count, prec, &s2l, &s2h, 0);
00537 *lv = s1l | s2l;
00538 *hv = s1h | s2h;
00539 }
00540
00541
00542
00543
00544
00545 void
00546 rrotate_double (l1, h1, count, prec, lv, hv)
00547 unsigned HOST_WIDE_INT l1;
00548 HOST_WIDE_INT h1, count;
00549 unsigned int prec;
00550 unsigned HOST_WIDE_INT *lv;
00551 HOST_WIDE_INT *hv;
00552 {
00553 unsigned HOST_WIDE_INT s1l, s2l;
00554 HOST_WIDE_INT s1h, s2h;
00555
00556 count %= prec;
00557 if (count < 0)
00558 count += prec;
00559
00560 rshift_double (l1, h1, count, prec, &s1l, &s1h, 0);
00561 lshift_double (l1, h1, prec - count, prec, &s2l, &s2h, 0);
00562 *lv = s1l | s2l;
00563 *hv = s1h | s2h;
00564 }
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575 int
00576 div_and_round_double (code, uns,
00577 lnum_orig, hnum_orig, lden_orig, hden_orig,
00578 lquo, hquo, lrem, hrem)
00579 enum tree_code code;
00580 int uns;
00581 unsigned HOST_WIDE_INT lnum_orig;
00582 HOST_WIDE_INT hnum_orig;
00583 unsigned HOST_WIDE_INT lden_orig;
00584 HOST_WIDE_INT hden_orig;
00585 unsigned HOST_WIDE_INT *lquo, *lrem;
00586 HOST_WIDE_INT *hquo, *hrem;
00587 {
00588 int quo_neg = 0;
00589 HOST_WIDE_INT num[4 + 1];
00590 HOST_WIDE_INT den[4], quo[4];
00591 int i, j;
00592 unsigned HOST_WIDE_INT work;
00593 unsigned HOST_WIDE_INT carry = 0;
00594 unsigned HOST_WIDE_INT lnum = lnum_orig;
00595 HOST_WIDE_INT hnum = hnum_orig;
00596 unsigned HOST_WIDE_INT lden = lden_orig;
00597 HOST_WIDE_INT hden = hden_orig;
00598 int overflow = 0;
00599
00600 if (hden == 0 && lden == 0)
00601 overflow = 1, lden = 1;
00602
00603
00604 if (!uns)
00605 {
00606 if (hnum < 0)
00607 {
00608 quo_neg = ~ quo_neg;
00609
00610 if (neg_double (lnum, hnum, &lnum, &hnum)
00611 && ((HOST_WIDE_INT) lden & hden) == -1)
00612 overflow = 1;
00613 }
00614 if (hden < 0)
00615 {
00616 quo_neg = ~ quo_neg;
00617 neg_double (lden, hden, &lden, &hden);
00618 }
00619 }
00620
00621 if (hnum == 0 && hden == 0)
00622 {
00623 *hquo = *hrem = 0;
00624
00625 *lquo = lnum / lden;
00626 goto finish_up;
00627 }
00628
00629 if (hnum == 0)
00630 {
00631
00632 *hquo = *lquo = 0;
00633 *hrem = hnum;
00634 *lrem = lnum;
00635 goto finish_up;
00636 }
00637
00638 memset ((char *) quo, 0, sizeof quo);
00639
00640 memset ((char *) num, 0, sizeof num);
00641 memset ((char *) den, 0, sizeof den);
00642
00643 encode (num, lnum, hnum);
00644 encode (den, lden, hden);
00645
00646
00647 if (hden == 0 && lden < (unsigned HOST_WIDE_INT) BASE)
00648 {
00649
00650 for (i = 4 - 1; i >= 0; i--)
00651 {
00652 work = num[i] + carry * BASE;
00653 quo[i] = work / lden;
00654 carry = work % lden;
00655 }
00656 }
00657 else
00658 {
00659
00660
00661 int num_hi_sig, den_hi_sig;
00662 unsigned HOST_WIDE_INT quo_est, scale;
00663
00664
00665 for (i = 4 - 1;; i--)
00666 if (den[i] != 0)
00667 {
00668 den_hi_sig = i;
00669 break;
00670 }
00671
00672
00673
00674
00675 scale = BASE / (den[den_hi_sig] + 1);
00676 if (scale > 1)
00677 {
00678 carry = 0;
00679 for (i = 0; i <= 4 - 1; i++)
00680 {
00681 work = (num[i] * scale) + carry;
00682 num[i] = LOWPART (work);
00683 carry = HIGHPART (work);
00684 }
00685
00686 num[4] = carry;
00687 carry = 0;
00688 for (i = 0; i <= 4 - 1; i++)
00689 {
00690 work = (den[i] * scale) + carry;
00691 den[i] = LOWPART (work);
00692 carry = HIGHPART (work);
00693 if (den[i] != 0) den_hi_sig = i;
00694 }
00695 }
00696
00697 num_hi_sig = 4;
00698
00699
00700 for (i = num_hi_sig - den_hi_sig - 1; i >= 0; i--)
00701 {
00702
00703
00704
00705 unsigned HOST_WIDE_INT tmp;
00706
00707 num_hi_sig = i + den_hi_sig + 1;
00708 work = num[num_hi_sig] * BASE + num[num_hi_sig - 1];
00709 if (num[num_hi_sig] != den[den_hi_sig])
00710 quo_est = work / den[den_hi_sig];
00711 else
00712 quo_est = BASE - 1;
00713
00714
00715 tmp = work - quo_est * den[den_hi_sig];
00716 if (tmp < BASE
00717 && (den[den_hi_sig - 1] * quo_est
00718 > (tmp * BASE + num[num_hi_sig - 2])))
00719 quo_est--;
00720
00721
00722
00723
00724
00725 carry = 0;
00726 for (j = 0; j <= den_hi_sig; j++)
00727 {
00728 work = quo_est * den[j] + carry;
00729 carry = HIGHPART (work);
00730 work = num[i + j] - LOWPART (work);
00731 num[i + j] = LOWPART (work);
00732 carry += HIGHPART (work) != 0;
00733 }
00734
00735
00736
00737 if (num[num_hi_sig] < (HOST_WIDE_INT) carry)
00738 {
00739 quo_est--;
00740 carry = 0;
00741 for (j = 0; j <= den_hi_sig; j++)
00742 {
00743 work = num[i + j] + den[j] + carry;
00744 carry = HIGHPART (work);
00745 num[i + j] = LOWPART (work);
00746 }
00747
00748 num [num_hi_sig] += carry;
00749 }
00750
00751
00752 quo[i] = quo_est;
00753 }
00754 }
00755
00756 decode (quo, lquo, hquo);
00757
00758 finish_up:
00759
00760 if (quo_neg)
00761 neg_double (*lquo, *hquo, lquo, hquo);
00762
00763
00764 mul_double (*lquo, *hquo, lden_orig, hden_orig, lrem, hrem);
00765 neg_double (*lrem, *hrem, lrem, hrem);
00766 add_double (lnum_orig, hnum_orig, *lrem, *hrem, lrem, hrem);
00767
00768 switch (code)
00769 {
00770 case TRUNC_DIV_EXPR:
00771 case TRUNC_MOD_EXPR:
00772 case EXACT_DIV_EXPR:
00773 return overflow;
00774
00775 case FLOOR_DIV_EXPR:
00776 case FLOOR_MOD_EXPR:
00777 if (quo_neg && (*lrem != 0 || *hrem != 0))
00778 {
00779
00780 add_double (*lquo, *hquo, (HOST_WIDE_INT) -1, (HOST_WIDE_INT) -1,
00781 lquo, hquo);
00782 }
00783 else
00784 return overflow;
00785 break;
00786
00787 case CEIL_DIV_EXPR:
00788 case CEIL_MOD_EXPR:
00789 if (!quo_neg && (*lrem != 0 || *hrem != 0))
00790 {
00791 add_double (*lquo, *hquo, (HOST_WIDE_INT) 1, (HOST_WIDE_INT) 0,
00792 lquo, hquo);
00793 }
00794 else
00795 return overflow;
00796 break;
00797
00798 case ROUND_DIV_EXPR:
00799 case ROUND_MOD_EXPR:
00800 {
00801 unsigned HOST_WIDE_INT labs_rem = *lrem;
00802 HOST_WIDE_INT habs_rem = *hrem;
00803 unsigned HOST_WIDE_INT labs_den = lden, ltwice;
00804 HOST_WIDE_INT habs_den = hden, htwice;
00805
00806
00807 if (*hrem < 0)
00808 neg_double (*lrem, *hrem, &labs_rem, &habs_rem);
00809 if (hden < 0)
00810 neg_double (lden, hden, &labs_den, &habs_den);
00811
00812
00813 mul_double ((HOST_WIDE_INT) 2, (HOST_WIDE_INT) 0,
00814 labs_rem, habs_rem, <wice, &htwice);
00815
00816 if (((unsigned HOST_WIDE_INT) habs_den
00817 < (unsigned HOST_WIDE_INT) htwice)
00818 || (((unsigned HOST_WIDE_INT) habs_den
00819 == (unsigned HOST_WIDE_INT) htwice)
00820 && (labs_den < ltwice)))
00821 {
00822 if (*hquo < 0)
00823
00824 add_double (*lquo, *hquo,
00825 (HOST_WIDE_INT) -1, (HOST_WIDE_INT) -1, lquo, hquo);
00826 else
00827
00828 add_double (*lquo, *hquo, (HOST_WIDE_INT) 1, (HOST_WIDE_INT) 0,
00829 lquo, hquo);
00830 }
00831 else
00832 return overflow;
00833 }
00834 break;
00835
00836 default:
00837 abort ();
00838 }
00839
00840
00841 mul_double (*lquo, *hquo, lden_orig, hden_orig, lrem, hrem);
00842 neg_double (*lrem, *hrem, lrem, hrem);
00843 add_double (lnum_orig, hnum_orig, *lrem, *hrem, lrem, hrem);
00844 return overflow;
00845 }
00846
00847
00848
00849
00850 static tree
00851 negate_expr (t)
00852 tree t;
00853 {
00854 tree type;
00855 tree tem;
00856
00857 if (t == 0)
00858 return 0;
00859
00860 type = TREE_TYPE (t);
00861 STRIP_SIGN_NOPS (t);
00862
00863 switch (TREE_CODE (t))
00864 {
00865 case INTEGER_CST:
00866 case REAL_CST:
00867 if (! TREE_UNSIGNED (type)
00868 && 0 != (tem = fold (build1 (NEGATE_EXPR, type, t)))
00869 && ! TREE_OVERFLOW (tem))
00870 return tem;
00871 break;
00872
00873 case NEGATE_EXPR:
00874 return convert (type, TREE_OPERAND (t, 0));
00875
00876 case MINUS_EXPR:
00877
00878 if (! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
00879 return convert (type,
00880 fold (build (MINUS_EXPR, TREE_TYPE (t),
00881 TREE_OPERAND (t, 1),
00882 TREE_OPERAND (t, 0))));
00883 break;
00884
00885 default:
00886 break;
00887 }
00888
00889 return convert (type, fold (build1 (NEGATE_EXPR, TREE_TYPE (t), t)));
00890 }
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912 static tree
00913 split_tree (in, code, conp, litp, minus_litp, negate_p)
00914 tree in;
00915 enum tree_code code;
00916 tree *conp, *litp, *minus_litp;
00917 int negate_p;
00918 {
00919 tree var = 0;
00920
00921 *conp = 0;
00922 *litp = 0;
00923 *minus_litp = 0;
00924
00925
00926 STRIP_SIGN_NOPS (in);
00927
00928 if (TREE_CODE (in) == INTEGER_CST || TREE_CODE (in) == REAL_CST)
00929 *litp = in;
00930 else if (TREE_CODE (in) == code
00931 || (! FLOAT_TYPE_P (TREE_TYPE (in))
00932
00933
00934
00935
00936 && ((code == PLUS_EXPR && TREE_CODE (in) == MINUS_EXPR)
00937 || (code == MINUS_EXPR && TREE_CODE (in) == PLUS_EXPR))))
00938 {
00939 tree op0 = TREE_OPERAND (in, 0);
00940 tree op1 = TREE_OPERAND (in, 1);
00941 int neg1_p = TREE_CODE (in) == MINUS_EXPR;
00942 int neg_litp_p = 0, neg_conp_p = 0, neg_var_p = 0;
00943
00944
00945 if (TREE_CODE (op0) == INTEGER_CST || TREE_CODE (op0) == REAL_CST)
00946 *litp = op0, op0 = 0;
00947 else if (TREE_CODE (op1) == INTEGER_CST || TREE_CODE (op1) == REAL_CST)
00948 *litp = op1, neg_litp_p = neg1_p, op1 = 0;
00949
00950 if (op0 != 0 && TREE_CONSTANT (op0))
00951 *conp = op0, op0 = 0;
00952 else if (op1 != 0 && TREE_CONSTANT (op1))
00953 *conp = op1, neg_conp_p = neg1_p, op1 = 0;
00954
00955
00956
00957 if (op0 != 0 && op1 != 0)
00958 var = in;
00959 else if (op0 != 0)
00960 var = op0;
00961 else
00962 var = op1, neg_var_p = neg1_p;
00963
00964
00965 if (neg_litp_p)
00966 *minus_litp = *litp, *litp = 0;
00967 if (neg_conp_p)
00968 *conp = negate_expr (*conp);
00969 if (neg_var_p)
00970 var = negate_expr (var);
00971 }
00972 else if (TREE_CONSTANT (in))
00973 *conp = in;
00974 else
00975 var = in;
00976
00977 if (negate_p)
00978 {
00979 if (*litp)
00980 *minus_litp = *litp, *litp = 0;
00981 else if (*minus_litp)
00982 *litp = *minus_litp, *minus_litp = 0;
00983 *conp = negate_expr (*conp);
00984 var = negate_expr (var);
00985 }
00986
00987 return var;
00988 }
00989
00990
00991
00992
00993
00994 static tree
00995 associate_trees (t1, t2, code, type)
00996 tree t1, t2;
00997 enum tree_code code;
00998 tree type;
00999 {
01000 if (t1 == 0)
01001 return t2;
01002 else if (t2 == 0)
01003 return t1;
01004
01005
01006
01007
01008 if (TREE_CODE (t1) == code || TREE_CODE (t2) == code
01009 || TREE_CODE (t1) == MINUS_EXPR || TREE_CODE (t2) == MINUS_EXPR)
01010 {
01011 if (code == PLUS_EXPR)
01012 {
01013 if (TREE_CODE (t1) == NEGATE_EXPR)
01014 return build (MINUS_EXPR, type, convert (type, t2),
01015 convert (type, TREE_OPERAND (t1, 0)));
01016 else if (TREE_CODE (t2) == NEGATE_EXPR)
01017 return build (MINUS_EXPR, type, convert (type, t1),
01018 convert (type, TREE_OPERAND (t2, 0)));
01019 }
01020 return build (code, type, convert (type, t1), convert (type, t2));
01021 }
01022
01023 return fold (build (code, type, convert (type, t1), convert (type, t2)));
01024 }
01025
01026
01027
01028
01029
01030
01031 static tree
01032 int_const_binop (code, arg1, arg2, notrunc)
01033 enum tree_code code;
01034 tree arg1, arg2;
01035 int notrunc;
01036 {
01037 unsigned HOST_WIDE_INT int1l, int2l;
01038 HOST_WIDE_INT int1h, int2h;
01039 unsigned HOST_WIDE_INT low;
01040 HOST_WIDE_INT hi;
01041 unsigned HOST_WIDE_INT garbagel;
01042 HOST_WIDE_INT garbageh;
01043 tree t;
01044 tree type = TREE_TYPE (arg1);
01045 int uns = TREE_UNSIGNED (type);
01046 int is_sizetype
01047 = (TREE_CODE (type) == INTEGER_TYPE && TYPE_IS_SIZETYPE (type));
01048 int overflow = 0;
01049 int no_overflow = 0;
01050
01051 int1l = TREE_INT_CST_LOW (arg1);
01052 int1h = TREE_INT_CST_HIGH (arg1);
01053 int2l = TREE_INT_CST_LOW (arg2);
01054 int2h = TREE_INT_CST_HIGH (arg2);
01055
01056 switch (code)
01057 {
01058 case BIT_IOR_EXPR:
01059 low = int1l | int2l, hi = int1h | int2h;
01060 break;
01061
01062 case BIT_XOR_EXPR:
01063 low = int1l ^ int2l, hi = int1h ^ int2h;
01064 break;
01065
01066 case BIT_AND_EXPR:
01067 low = int1l & int2l, hi = int1h & int2h;
01068 break;
01069
01070 case BIT_ANDTC_EXPR:
01071 low = int1l & ~int2l, hi = int1h & ~int2h;
01072 break;
01073
01074 case RSHIFT_EXPR:
01075 int2l = -int2l;
01076 case LSHIFT_EXPR:
01077
01078
01079
01080 lshift_double (int1l, int1h, int2l, TYPE_PRECISION (type),
01081 &low, &hi, !uns);
01082 no_overflow = 1;
01083 break;
01084
01085 case RROTATE_EXPR:
01086 int2l = - int2l;
01087 case LROTATE_EXPR:
01088 lrotate_double (int1l, int1h, int2l, TYPE_PRECISION (type),
01089 &low, &hi);
01090 break;
01091
01092 case PLUS_EXPR:
01093 overflow = add_double (int1l, int1h, int2l, int2h, &low, &hi);
01094 break;
01095
01096 case MINUS_EXPR:
01097 neg_double (int2l, int2h, &low, &hi);
01098 add_double (int1l, int1h, low, hi, &low, &hi);
01099 overflow = OVERFLOW_SUM_SIGN (hi, int2h, int1h);
01100 break;
01101
01102 case MULT_EXPR:
01103 overflow = mul_double (int1l, int1h, int2l, int2h, &low, &hi);
01104 break;
01105
01106 case TRUNC_DIV_EXPR:
01107 case FLOOR_DIV_EXPR: case CEIL_DIV_EXPR:
01108 case EXACT_DIV_EXPR:
01109
01110 if (int2h == 0 && (HOST_WIDE_INT) int2l > 0
01111 && ! TREE_CONSTANT_OVERFLOW (arg1)
01112 && ! TREE_CONSTANT_OVERFLOW (arg2)
01113 && int1h == 0 && (HOST_WIDE_INT) int1l >= 0)
01114 {
01115 if (code == CEIL_DIV_EXPR)
01116 int1l += int2l - 1;
01117
01118 low = int1l / int2l, hi = 0;
01119 break;
01120 }
01121
01122
01123
01124 case ROUND_DIV_EXPR:
01125 if (int2h == 0 && int2l == 1)
01126 {
01127 low = int1l, hi = int1h;
01128 break;
01129 }
01130 if (int1l == int2l && int1h == int2h
01131 && ! (int1l == 0 && int1h == 0))
01132 {
01133 low = 1, hi = 0;
01134 break;
01135 }
01136 overflow = div_and_round_double (code, uns, int1l, int1h, int2l, int2h,
01137 &low, &hi, &garbagel, &garbageh);
01138 break;
01139
01140 case TRUNC_MOD_EXPR:
01141 case FLOOR_MOD_EXPR: case CEIL_MOD_EXPR:
01142
01143 if (int2h == 0 && (HOST_WIDE_INT) int2l > 0
01144 && ! TREE_CONSTANT_OVERFLOW (arg1)
01145 && ! TREE_CONSTANT_OVERFLOW (arg2)
01146 && int1h == 0 && (HOST_WIDE_INT) int1l >= 0)
01147 {
01148 if (code == CEIL_MOD_EXPR)
01149 int1l += int2l - 1;
01150 low = int1l % int2l, hi = 0;
01151 break;
01152 }
01153
01154
01155
01156 case ROUND_MOD_EXPR:
01157 overflow = div_and_round_double (code, uns,
01158 int1l, int1h, int2l, int2h,
01159 &garbagel, &garbageh, &low, &hi);
01160 break;
01161
01162 case MIN_EXPR:
01163 case MAX_EXPR:
01164 if (uns)
01165 low = (((unsigned HOST_WIDE_INT) int1h
01166 < (unsigned HOST_WIDE_INT) int2h)
01167 || (((unsigned HOST_WIDE_INT) int1h
01168 == (unsigned HOST_WIDE_INT) int2h)
01169 && int1l < int2l));
01170 else
01171 low = (int1h < int2h
01172 || (int1h == int2h && int1l < int2l));
01173
01174 if (low == (code == MIN_EXPR))
01175 low = int1l, hi = int1h;
01176 else
01177 low = int2l, hi = int2h;
01178 break;
01179
01180 default:
01181 abort ();
01182 }
01183
01184
01185
01186
01187 if (is_sizetype
01188 && ((hi == 0 && (HOST_WIDE_INT) low >= 0)
01189 || (hi == -1 && (HOST_WIDE_INT) low < 0))
01190 && overflow == 0 && ! TREE_OVERFLOW (arg1) && ! TREE_OVERFLOW (arg2))
01191 return size_int_type_wide (low, type);
01192 else
01193 {
01194 t = build_int_2 (low, hi);
01195 TREE_TYPE (t) = TREE_TYPE (arg1);
01196 }
01197
01198 TREE_OVERFLOW (t)
01199 = ((notrunc
01200 ? (!uns || is_sizetype) && overflow
01201 : (force_fit_type (t, (!uns || is_sizetype) && overflow)
01202 && ! no_overflow))
01203 | TREE_OVERFLOW (arg1)
01204 | TREE_OVERFLOW (arg2));
01205
01206
01207
01208 if (is_sizetype
01209 && ! TREE_OVERFLOW (t)
01210 && (TREE_INT_CST_HIGH (t) != hi
01211 || TREE_INT_CST_LOW (t) != low))
01212 TREE_OVERFLOW (t) = 1;
01213
01214 TREE_CONSTANT_OVERFLOW (t) = (TREE_OVERFLOW (t)
01215 | TREE_CONSTANT_OVERFLOW (arg1)
01216 | TREE_CONSTANT_OVERFLOW (arg2));
01217 return t;
01218 }
01219
01220
01221
01222
01223
01224
01225
01226 static tree
01227 const_binop (code, arg1, arg2, notrunc)
01228 enum tree_code code;
01229 tree arg1, arg2;
01230 int notrunc;
01231 {
01232 STRIP_NOPS (arg1);
01233 STRIP_NOPS (arg2);
01234
01235 if (TREE_CODE (arg1) == INTEGER_CST)
01236 return int_const_binop (code, arg1, arg2, notrunc);
01237
01238 if (TREE_CODE (arg1) == REAL_CST)
01239 {
01240 REAL_VALUE_TYPE d1;
01241 REAL_VALUE_TYPE d2;
01242 REAL_VALUE_TYPE value;
01243 tree t;
01244
01245 d1 = TREE_REAL_CST (arg1);
01246 d2 = TREE_REAL_CST (arg2);
01247
01248
01249
01250 if (REAL_VALUE_ISNAN (d1))
01251 return arg1;
01252 else if (REAL_VALUE_ISNAN (d2))
01253 return arg2;
01254
01255 REAL_ARITHMETIC (value, code, d1, d2);
01256
01257 t = build_real (TREE_TYPE (arg1),
01258 real_value_truncate (TYPE_MODE (TREE_TYPE (arg1)),
01259 value));
01260
01261 TREE_OVERFLOW (t)
01262 = (force_fit_type (t, 0)
01263 | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2));
01264 TREE_CONSTANT_OVERFLOW (t)
01265 = TREE_OVERFLOW (t)
01266 | TREE_CONSTANT_OVERFLOW (arg1)
01267 | TREE_CONSTANT_OVERFLOW (arg2);
01268 return t;
01269 }
01270 if (TREE_CODE (arg1) == COMPLEX_CST)
01271 {
01272 tree type = TREE_TYPE (arg1);
01273 tree r1 = TREE_REALPART (arg1);
01274 tree i1 = TREE_IMAGPART (arg1);
01275 tree r2 = TREE_REALPART (arg2);
01276 tree i2 = TREE_IMAGPART (arg2);
01277 tree t;
01278
01279 switch (code)
01280 {
01281 case PLUS_EXPR:
01282 t = build_complex (type,
01283 const_binop (PLUS_EXPR, r1, r2, notrunc),
01284 const_binop (PLUS_EXPR, i1, i2, notrunc));
01285 break;
01286
01287 case MINUS_EXPR:
01288 t = build_complex (type,
01289 const_binop (MINUS_EXPR, r1, r2, notrunc),
01290 const_binop (MINUS_EXPR, i1, i2, notrunc));
01291 break;
01292
01293 case MULT_EXPR:
01294 t = build_complex (type,
01295 const_binop (MINUS_EXPR,
01296 const_binop (MULT_EXPR,
01297 r1, r2, notrunc),
01298 const_binop (MULT_EXPR,
01299 i1, i2, notrunc),
01300 notrunc),
01301 const_binop (PLUS_EXPR,
01302 const_binop (MULT_EXPR,
01303 r1, i2, notrunc),
01304 const_binop (MULT_EXPR,
01305 i1, r2, notrunc),
01306 notrunc));
01307 break;
01308
01309 case RDIV_EXPR:
01310 {
01311 tree magsquared
01312 = const_binop (PLUS_EXPR,
01313 const_binop (MULT_EXPR, r2, r2, notrunc),
01314 const_binop (MULT_EXPR, i2, i2, notrunc),
01315 notrunc);
01316
01317 t = build_complex (type,
01318 const_binop
01319 (INTEGRAL_TYPE_P (TREE_TYPE (r1))
01320 ? TRUNC_DIV_EXPR : RDIV_EXPR,
01321 const_binop (PLUS_EXPR,
01322 const_binop (MULT_EXPR, r1, r2,
01323 notrunc),
01324 const_binop (MULT_EXPR, i1, i2,
01325 notrunc),
01326 notrunc),
01327 magsquared, notrunc),
01328 const_binop
01329 (INTEGRAL_TYPE_P (TREE_TYPE (r1))
01330 ? TRUNC_DIV_EXPR : RDIV_EXPR,
01331 const_binop (MINUS_EXPR,
01332 const_binop (MULT_EXPR, i1, r2,
01333 notrunc),
01334 const_binop (MULT_EXPR, r1, i2,
01335 notrunc),
01336 notrunc),
01337 magsquared, notrunc));
01338 }
01339 break;
01340
01341 default:
01342 abort ();
01343 }
01344 return t;
01345 }
01346 return 0;
01347 }
01348
01349
01350
01351
01352
01353
01354 static hashval_t
01355 size_htab_hash (x)
01356 const void *x;
01357 {
01358 tree t = (tree) x;
01359
01360 return (TREE_INT_CST_HIGH (t) ^ TREE_INT_CST_LOW (t)
01361 ^ htab_hash_pointer (TREE_TYPE (t))
01362 ^ (TREE_OVERFLOW (t) << 20));
01363 }
01364
01365
01366
01367
01368 static int
01369 size_htab_eq (x, y)
01370 const void *x;
01371 const void *y;
01372 {
01373 tree xt = (tree) x;
01374 tree yt = (tree) y;
01375
01376 return (TREE_INT_CST_HIGH (xt) == TREE_INT_CST_HIGH (yt)
01377 && TREE_INT_CST_LOW (xt) == TREE_INT_CST_LOW (yt)
01378 && TREE_TYPE (xt) == TREE_TYPE (yt)
01379 && TREE_OVERFLOW (xt) == TREE_OVERFLOW (yt));
01380 }
01381
01382
01383
01384
01385 tree
01386 size_int_wide (number, kind)
01387 HOST_WIDE_INT number;
01388 enum size_type_kind kind;
01389 {
01390 return size_int_type_wide (number, sizetype_tab[(int) kind]);
01391 }
01392
01393
01394
01395 static GTY (()) tree new_const;
01396 static GTY ((if_marked ("ggc_marked_p"), param_is (union tree_node)))
01397 htab_t size_htab;
01398
01399 tree
01400 size_int_type_wide (number, type)
01401 HOST_WIDE_INT number;
01402 tree type;
01403 {
01404 PTR *slot;
01405
01406 if (size_htab == 0)
01407 {
01408 size_htab = htab_create (1024, size_htab_hash, size_htab_eq, NULL);
01409 new_const = make_node (INTEGER_CST);
01410 }
01411
01412
01413
01414
01415 TREE_INT_CST_LOW (new_const) = number;
01416 TREE_INT_CST_HIGH (new_const) = number < 0 ? -1 : 0;
01417 TREE_TYPE (new_const) = type;
01418 TREE_OVERFLOW (new_const) = TREE_CONSTANT_OVERFLOW (new_const)
01419 = force_fit_type (new_const, 0);
01420
01421 slot = htab_find_slot (size_htab, new_const, INSERT);
01422 if (*slot == 0)
01423 {
01424 tree t = new_const;
01425
01426 *slot = (PTR) new_const;
01427 new_const = make_node (INTEGER_CST);
01428 return t;
01429 }
01430 else
01431 return (tree) *slot;
01432 }
01433
01434
01435
01436
01437
01438
01439 tree
01440 size_binop (code, arg0, arg1)
01441 enum tree_code code;
01442 tree arg0, arg1;
01443 {
01444 tree type = TREE_TYPE (arg0);
01445
01446 if (TREE_CODE (type) != INTEGER_TYPE || ! TYPE_IS_SIZETYPE (type)
01447 || type != TREE_TYPE (arg1))
01448 abort ();
01449
01450
01451 if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
01452 {
01453
01454 if (code == PLUS_EXPR && integer_zerop (arg0))
01455 return arg1;
01456 else if ((code == MINUS_EXPR || code == PLUS_EXPR)
01457 && integer_zerop (arg1))
01458 return arg0;
01459 else if (code == MULT_EXPR && integer_onep (arg0))
01460 return arg1;
01461
01462
01463 return int_const_binop (code, arg0, arg1, 0);
01464 }
01465
01466 if (arg0 == error_mark_node || arg1 == error_mark_node)
01467 return error_mark_node;
01468
01469 return fold (build (code, type, arg0, arg1));
01470 }
01471
01472
01473
01474
01475
01476 tree
01477 size_diffop (arg0, arg1)
01478 tree arg0, arg1;
01479 {
01480 tree type = TREE_TYPE (arg0);
01481 tree ctype;
01482
01483 if (TREE_CODE (type) != INTEGER_TYPE || ! TYPE_IS_SIZETYPE (type)
01484 || type != TREE_TYPE (arg1))
01485 abort ();
01486
01487
01488 if (! TREE_UNSIGNED (type))
01489 return size_binop (MINUS_EXPR, arg0, arg1);
01490
01491 ctype = (type == bitsizetype || type == ubitsizetype
01492 ? sbitsizetype : ssizetype);
01493
01494
01495
01496
01497 if (TREE_CODE (arg0) != INTEGER_CST || TREE_CODE (arg1) != INTEGER_CST)
01498 return size_binop (MINUS_EXPR, convert (ctype, arg0),
01499 convert (ctype, arg1));
01500
01501
01502
01503
01504
01505 if (tree_int_cst_equal (arg0, arg1))
01506 return convert (ctype, integer_zero_node);
01507 else if (tree_int_cst_lt (arg1, arg0))
01508 return convert (ctype, size_binop (MINUS_EXPR, arg0, arg1));
01509 else
01510 return size_binop (MINUS_EXPR, convert (ctype, integer_zero_node),
01511 convert (ctype, size_binop (MINUS_EXPR, arg1, arg0)));
01512 }
01513
01514
01515
01516
01517
01518 static tree
01519 fold_convert (t, arg1)
01520 tree t;
01521 tree arg1;
01522 {
01523 tree type = TREE_TYPE (t);
01524 int overflow = 0;
01525
01526 if (POINTER_TYPE_P (type) || INTEGRAL_TYPE_P (type))
01527 {
01528 if (TREE_CODE (arg1) == INTEGER_CST)
01529 {
01530
01531
01532 if (TYPE_PRECISION (type) > 2 * HOST_BITS_PER_WIDE_INT)
01533 return t;
01534
01535
01536
01537 if (TREE_CODE (type) == INTEGER_TYPE && TYPE_IS_SIZETYPE (type)
01538 && !TREE_CONSTANT_OVERFLOW (arg1)
01539 && compare_tree_int (arg1, 10000) < 0)
01540 return size_int_type_wide (TREE_INT_CST_LOW (arg1), type);
01541
01542
01543
01544 t = build_int_2 (TREE_INT_CST_LOW (arg1),
01545 TREE_INT_CST_HIGH (arg1));
01546 TREE_TYPE (t) = type;
01547
01548
01549
01550
01551
01552 TREE_OVERFLOW (t)
01553 = ((force_fit_type (t,
01554 (TREE_INT_CST_HIGH (arg1) < 0
01555 && (TREE_UNSIGNED (type)
01556 < TREE_UNSIGNED (TREE_TYPE (arg1)))))
01557 && ! POINTER_TYPE_P (TREE_TYPE (arg1)))
01558 || TREE_OVERFLOW (arg1));
01559 TREE_CONSTANT_OVERFLOW (t)
01560 = TREE_OVERFLOW (t) | TREE_CONSTANT_OVERFLOW (arg1);
01561 }
01562 else if (TREE_CODE (arg1) == REAL_CST)
01563 {
01564
01565
01566 REAL_VALUE_TYPE x;
01567 REAL_VALUE_TYPE l;
01568 REAL_VALUE_TYPE u;
01569 tree type1 = TREE_TYPE (arg1);
01570 int no_upper_bound;
01571
01572 x = TREE_REAL_CST (arg1);
01573 l = real_value_from_int_cst (type1, TYPE_MIN_VALUE (type));
01574
01575 no_upper_bound = (TYPE_MAX_VALUE (type) == NULL);
01576 if (!no_upper_bound)
01577 u = real_value_from_int_cst (type1, TYPE_MAX_VALUE (type));
01578
01579
01580
01581
01582 REAL_ARITHMETIC (l, MINUS_EXPR, l, dconst1);
01583 if (!no_upper_bound)
01584 REAL_ARITHMETIC (u, PLUS_EXPR, u, dconst1);
01585
01586
01587 if (REAL_VALUE_ISNAN (x))
01588 overflow = 1, x = dconst0;
01589 else if (! (REAL_VALUES_LESS (l, x)
01590 && !no_upper_bound
01591 && REAL_VALUES_LESS (x, u)))
01592 overflow = 1;
01593
01594 {
01595 HOST_WIDE_INT low, high;
01596 REAL_VALUE_TO_INT (&low, &high, x);
01597 t = build_int_2 (low, high);
01598 }
01599 TREE_TYPE (t) = type;
01600 TREE_OVERFLOW (t)
01601 = TREE_OVERFLOW (arg1) | force_fit_type (t, overflow);
01602 TREE_CONSTANT_OVERFLOW (t)
01603 = TREE_OVERFLOW (t) | TREE_CONSTANT_OVERFLOW (arg1);
01604 }
01605 TREE_TYPE (t) = type;
01606 }
01607 else if (TREE_CODE (type) == REAL_TYPE)
01608 {
01609 if (TREE_CODE (arg1) == INTEGER_CST)
01610 return build_real_from_int_cst (type, arg1);
01611 if (TREE_CODE (arg1) == REAL_CST)
01612 {
01613 if (REAL_VALUE_ISNAN (TREE_REAL_CST (arg1)))
01614 {
01615
01616
01617 t = copy_node (arg1);
01618 TREE_TYPE (t) = type;
01619 return t;
01620 }
01621
01622 t = build_real (type,
01623 real_value_truncate (TYPE_MODE (type),
01624 TREE_REAL_CST (arg1)));
01625
01626 TREE_OVERFLOW (t)
01627 = TREE_OVERFLOW (arg1) | force_fit_type (t, 0);
01628 TREE_CONSTANT_OVERFLOW (t)
01629 = TREE_OVERFLOW (t) | TREE_CONSTANT_OVERFLOW (arg1);
01630 return t;
01631 }
01632 }
01633 TREE_CONSTANT (t) = 1;
01634 return t;
01635 }
01636
01637
01638
01639 tree
01640 non_lvalue (x)
01641 tree x;
01642 {
01643 tree result;
01644
01645
01646 if (TREE_CODE (x) == NON_LVALUE_EXPR
01647 || TREE_CODE (x) == INTEGER_CST
01648 || TREE_CODE (x) == REAL_CST
01649 || TREE_CODE (x) == STRING_CST
01650 || TREE_CODE (x) == ADDR_EXPR)
01651 return x;
01652
01653 result = build1 (NON_LVALUE_EXPR, TREE_TYPE (x), x);
01654 TREE_CONSTANT (result) = TREE_CONSTANT (x);
01655 return result;
01656 }
01657
01658
01659
01660
01661 int pedantic_lvalues;
01662
01663
01664
01665
01666 tree
01667 pedantic_non_lvalue (x)
01668 tree x;
01669 {
01670 if (pedantic_lvalues)
01671 return non_lvalue (x);
01672 else
01673 return x;
01674 }
01675
01676
01677
01678
01679
01680 static enum tree_code
01681 invert_tree_comparison (code)
01682 enum tree_code code;
01683 {
01684 switch (code)
01685 {
01686 case EQ_EXPR:
01687 return NE_EXPR;
01688 case NE_EXPR:
01689 return EQ_EXPR;
01690 case GT_EXPR:
01691 return LE_EXPR;
01692 case GE_EXPR:
01693 return LT_EXPR;
01694 case LT_EXPR:
01695 return GE_EXPR;
01696 case LE_EXPR:
01697 return GT_EXPR;
01698 default:
01699 abort ();
01700 }
01701 }
01702
01703
01704
01705
01706 static enum tree_code
01707 swap_tree_comparison (code)
01708 enum tree_code code;
01709 {
01710 switch (code)
01711 {
01712 case EQ_EXPR:
01713 case NE_EXPR:
01714 return code;
01715 case GT_EXPR:
01716 return LT_EXPR;
01717 case GE_EXPR:
01718 return LE_EXPR;
01719 case LT_EXPR:
01720 return GT_EXPR;
01721 case LE_EXPR:
01722 return GE_EXPR;
01723 default:
01724 abort ();
01725 }
01726 }
01727
01728
01729
01730
01731
01732
01733 static int
01734 comparison_to_compcode (code)
01735 enum tree_code code;
01736 {
01737 switch (code)
01738 {
01739 case LT_EXPR:
01740 return COMPCODE_LT;
01741 case EQ_EXPR:
01742 return COMPCODE_EQ;
01743 case LE_EXPR:
01744 return COMPCODE_LE;
01745 case GT_EXPR:
01746 return COMPCODE_GT;
01747 case NE_EXPR:
01748 return COMPCODE_NE;
01749 case GE_EXPR:
01750 return COMPCODE_GE;
01751 default:
01752 abort ();
01753 }
01754 }
01755
01756
01757
01758
01759
01760 static enum tree_code
01761 compcode_to_comparison (code)
01762 int code;
01763 {
01764 switch (code)
01765 {
01766 case COMPCODE_LT:
01767 return LT_EXPR;
01768 case COMPCODE_EQ:
01769 return EQ_EXPR;
01770 case COMPCODE_LE:
01771 return LE_EXPR;
01772 case COMPCODE_GT:
01773 return GT_EXPR;
01774 case COMPCODE_NE:
01775 return NE_EXPR;
01776 case COMPCODE_GE:
01777 return GE_EXPR;
01778 default:
01779 abort ();
01780 }
01781 }
01782
01783
01784
01785 static int
01786 truth_value_p (code)
01787 enum tree_code code;
01788 {
01789 return (TREE_CODE_CLASS (code) == '<'
01790 || code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR
01791 || code == TRUTH_OR_EXPR || code == TRUTH_ORIF_EXPR
01792 || code == TRUTH_XOR_EXPR || code == TRUTH_NOT_EXPR);
01793 }
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803 int
01804 operand_equal_p (arg0, arg1, only_const)
01805 tree arg0, arg1;
01806 int only_const;
01807 {
01808
01809
01810
01811 if (TREE_UNSIGNED (TREE_TYPE (arg0)) != TREE_UNSIGNED (TREE_TYPE (arg1)))
01812 return 0;
01813
01814 STRIP_NOPS (arg0);
01815 STRIP_NOPS (arg1);
01816
01817 if (TREE_CODE (arg0) != TREE_CODE (arg1)
01818
01819
01820 || TREE_CODE (TREE_TYPE (arg0)) == ERROR_MARK
01821 || TREE_CODE (TREE_TYPE (arg1)) == ERROR_MARK
01822 || TYPE_MODE (TREE_TYPE (arg0)) != TYPE_MODE (TREE_TYPE (arg1)))
01823 return 0;
01824
01825
01826
01827
01828
01829
01830
01831
01832 if (arg0 == arg1 && ! only_const
01833 && (TREE_CODE (arg0) == SAVE_EXPR
01834 || (! TREE_SIDE_EFFECTS (arg0) && ! TREE_SIDE_EFFECTS (arg1))))
01835 return 1;
01836
01837
01838
01839 if (TREE_CONSTANT (arg0) && TREE_CONSTANT (arg1))
01840 switch (TREE_CODE (arg0))
01841 {
01842 case INTEGER_CST:
01843 return (! TREE_CONSTANT_OVERFLOW (arg0)
01844 && ! TREE_CONSTANT_OVERFLOW (arg1)
01845 && tree_int_cst_equal (arg0, arg1));
01846
01847 case REAL_CST:
01848 return (! TREE_CONSTANT_OVERFLOW (arg0)
01849 && ! TREE_CONSTANT_OVERFLOW (arg1)
01850 && REAL_VALUES_IDENTICAL (TREE_REAL_CST (arg0),
01851 TREE_REAL_CST (arg1)));
01852
01853 case VECTOR_CST:
01854 {
01855 tree v1, v2;
01856
01857 if (TREE_CONSTANT_OVERFLOW (arg0)
01858 || TREE_CONSTANT_OVERFLOW (arg1))
01859 return 0;
01860
01861 v1 = TREE_VECTOR_CST_ELTS (arg0);
01862 v2 = TREE_VECTOR_CST_ELTS (arg1);
01863 while (v1 && v2)
01864 {
01865 if (!operand_equal_p (v1, v2, only_const))
01866 return 0;
01867 v1 = TREE_CHAIN (v1);
01868 v2 = TREE_CHAIN (v2);
01869 }
01870
01871 return 1;
01872 }
01873
01874 case COMPLEX_CST:
01875 return (operand_equal_p (TREE_REALPART (arg0), TREE_REALPART (arg1),
01876 only_const)
01877 && operand_equal_p (TREE_IMAGPART (arg0), TREE_IMAGPART (arg1),
01878 only_const));
01879
01880 case STRING_CST:
01881 return (TREE_STRING_LENGTH (arg0) == TREE_STRING_LENGTH (arg1)
01882 && ! memcmp (TREE_STRING_POINTER (arg0),
01883 TREE_STRING_POINTER (arg1),
01884 TREE_STRING_LENGTH (arg0)));
01885
01886 case ADDR_EXPR:
01887 return operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0),
01888 0);
01889 default:
01890 break;
01891 }
01892
01893 if (only_const)
01894 return 0;
01895
01896 switch (TREE_CODE_CLASS (TREE_CODE (arg0)))
01897 {
01898 case '1':
01899
01900 if ((TREE_CODE (arg0) == NOP_EXPR || TREE_CODE (arg0) == CONVERT_EXPR)
01901 && (TREE_UNSIGNED (TREE_TYPE (arg0))
01902 != TREE_UNSIGNED (TREE_TYPE (arg1))))
01903 return 0;
01904
01905 return operand_equal_p (TREE_OPERAND (arg0, 0),
01906 TREE_OPERAND (arg1, 0), 0);
01907
01908 case '<':
01909 case '2':
01910 if (operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0), 0)
01911 && operand_equal_p (TREE_OPERAND (arg0, 1), TREE_OPERAND (arg1, 1),
01912 0))
01913 return 1;
01914
01915
01916 return ((TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MULT_EXPR
01917 || TREE_CODE (arg0) == MIN_EXPR || TREE_CODE (arg0) == MAX_EXPR
01918 || TREE_CODE (arg0) == BIT_IOR_EXPR
01919 || TREE_CODE (arg0) == BIT_XOR_EXPR
01920 || TREE_CODE (arg0) == BIT_AND_EXPR
01921 || TREE_CODE (arg0) == NE_EXPR || TREE_CODE (arg0) == EQ_EXPR)
01922 && operand_equal_p (TREE_OPERAND (arg0, 0),
01923 TREE_OPERAND (arg1, 1), 0)
01924 && operand_equal_p (TREE_OPERAND (arg0, 1),
01925 TREE_OPERAND (arg1, 0), 0));
01926
01927 case 'r':
01928
01929
01930 if (TREE_SIDE_EFFECTS (arg0)
01931 || TREE_SIDE_EFFECTS (arg1))
01932 return 0;
01933
01934 switch (TREE_CODE (arg0))
01935 {
01936 case INDIRECT_REF:
01937 return operand_equal_p (TREE_OPERAND (arg0, 0),
01938 TREE_OPERAND (arg1, 0), 0);
01939
01940 case COMPONENT_REF:
01941 case ARRAY_REF:
01942 case ARRAY_RANGE_REF:
01943 return (operand_equal_p (TREE_OPERAND (arg0, 0),
01944 TREE_OPERAND (arg1, 0), 0)
01945 && operand_equal_p (TREE_OPERAND (arg0, 1),
01946 TREE_OPERAND (arg1, 1), 0));
01947
01948 case BIT_FIELD_REF:
01949 return (operand_equal_p (TREE_OPERAND (arg0, 0),
01950 TREE_OPERAND (arg1, 0), 0)
01951 && operand_equal_p (TREE_OPERAND (arg0, 1),
01952 TREE_OPERAND (arg1, 1), 0)
01953 && operand_equal_p (TREE_OPERAND (arg0, 2),
01954 TREE_OPERAND (arg1, 2), 0));
01955 default:
01956 return 0;
01957 }
01958
01959 case 'e':
01960 if (TREE_CODE (arg0) == RTL_EXPR)
01961 return rtx_equal_p (RTL_EXPR_RTL (arg0), RTL_EXPR_RTL (arg1));
01962 return 0;
01963
01964 default:
01965 return 0;
01966 }
01967 }
01968
01969
01970
01971
01972
01973
01974 static int
01975 operand_equal_for_comparison_p (arg0, arg1, other)
01976 tree arg0, arg1;
01977 tree other;
01978 {
01979 int unsignedp1, unsignedpo;
01980 tree primarg0, primarg1, primother;
01981 unsigned int correct_width;
01982
01983 if (operand_equal_p (arg0, arg1, 0))
01984 return 1;
01985
01986 if (! INTEGRAL_TYPE_P (TREE_TYPE (arg0))
01987 || ! INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
01988 return 0;
01989
01990
01991
01992
01993 primarg0 = arg0, primarg1 = arg1;
01994 STRIP_NOPS (primarg0);
01995 STRIP_NOPS (primarg1);
01996 if (operand_equal_p (primarg0, primarg1, 0))
01997 return 1;
01998
01999
02000
02001
02002
02003
02004
02005 primarg1 = get_narrower (arg1, &unsignedp1);
02006 primother = get_narrower (other, &unsignedpo);
02007
02008 correct_width = TYPE_PRECISION (TREE_TYPE (arg1));
02009 if (unsignedp1 == unsignedpo
02010 && TYPE_PRECISION (TREE_TYPE (primarg1)) < correct_width
02011 && TYPE_PRECISION (TREE_TYPE (primother)) < correct_width)
02012 {
02013 tree type = TREE_TYPE (arg0);
02014
02015
02016
02017 primarg1 = convert ((*lang_hooks.types.signed_or_unsigned_type)
02018 (unsignedp1, TREE_TYPE (primarg1)), primarg1);
02019
02020 if (operand_equal_p (arg0, convert (type, primarg1), 0))
02021 return 1;
02022 }
02023
02024 return 0;
02025 }
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035
02036
02037 static int
02038 twoval_comparison_p (arg, cval1, cval2, save_p)
02039 tree arg;
02040 tree *cval1, *cval2;
02041 int *save_p;
02042 {
02043 enum tree_code code = TREE_CODE (arg);
02044 char class = TREE_CODE_CLASS (code);
02045
02046
02047 if (class == 'e' && code == TRUTH_NOT_EXPR)
02048 class = '1';
02049 else if (class == 'e'
02050 && (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR
02051 || code == COMPOUND_EXPR))
02052 class = '2';
02053
02054 else if (class == 'e' && code == SAVE_EXPR && SAVE_EXPR_RTL (arg) == 0
02055 && ! TREE_SIDE_EFFECTS (TREE_OPERAND (arg, 0)))
02056 {
02057
02058
02059 if (*cval1 || *cval2)
02060 return 0;
02061
02062 class = '1';
02063 *save_p = 1;
02064 }
02065
02066 switch (class)
02067 {
02068 case '1':
02069 return twoval_comparison_p (TREE_OPERAND (arg, 0), cval1, cval2, save_p);
02070
02071 case '2':
02072 return (twoval_comparison_p (TREE_OPERAND (arg, 0), cval1, cval2, save_p)
02073 && twoval_comparison_p (TREE_OPERAND (arg, 1),
02074 cval1, cval2, save_p));
02075
02076 case 'c':
02077 return 1;
02078
02079 case 'e':
02080 if (code == COND_EXPR)
02081 return (twoval_comparison_p (TREE_OPERAND (arg, 0),
02082 cval1, cval2, save_p)
02083 && twoval_comparison_p (TREE_OPERAND (arg, 1),
02084 cval1, cval2, save_p)
02085 && twoval_comparison_p (TREE_OPERAND (arg, 2),
02086 cval1, cval2, save_p));
02087 return 0;
02088
02089 case '<':
02090
02091
02092
02093
02094
02095
02096 if (operand_equal_p (TREE_OPERAND (arg, 0),
02097 TREE_OPERAND (arg, 1), 0))
02098 return 0;
02099
02100 if (*cval1 == 0)
02101 *cval1 = TREE_OPERAND (arg, 0);
02102 else if (operand_equal_p (*cval1, TREE_OPERAND (arg, 0), 0))
02103 ;
02104 else if (*cval2 == 0)
02105 *cval2 = TREE_OPERAND (arg, 0);
02106 else if (operand_equal_p (*cval2, TREE_OPERAND (arg, 0), 0))
02107 ;
02108 else
02109 return 0;
02110
02111 if (operand_equal_p (*cval1, TREE_OPERAND (arg, 1), 0))
02112 ;
02113 else if (*cval2 == 0)
02114 *cval2 = TREE_OPERAND (arg, 1);
02115 else if (operand_equal_p (*cval2, TREE_OPERAND (arg, 1), 0))
02116 ;
02117 else
02118 return 0;
02119
02120 return 1;
02121
02122 default:
02123 return 0;
02124 }
02125 }
02126
02127
02128
02129
02130
02131
02132 static tree
02133 eval_subst (arg, old0, new0, old1, new1)
02134 tree arg;
02135 tree old0, new0, old1, new1;
02136 {
02137 tree type = TREE_TYPE (arg);
02138 enum tree_code code = TREE_CODE (arg);
02139 char class = TREE_CODE_CLASS (code);
02140
02141
02142 if (class == 'e' && code == TRUTH_NOT_EXPR)
02143 class = '1';
02144 else if (class == 'e'
02145 && (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR))
02146 class = '2';
02147
02148 switch (class)
02149 {
02150 case '1':
02151 return fold (build1 (code, type,
02152 eval_subst (TREE_OPERAND (arg, 0),
02153 old0, new0, old1, new1)));
02154
02155 case '2':
02156 return fold (build (code, type,
02157 eval_subst (TREE_OPERAND (arg, 0),
02158 old0, new0, old1, new1),
02159 eval_subst (TREE_OPERAND (arg, 1),
02160 old0, new0, old1, new1)));
02161
02162 case 'e':
02163 switch (code)
02164 {
02165 case SAVE_EXPR:
02166 return eval_subst (TREE_OPERAND (arg, 0), old0, new0, old1, new1);
02167
02168 case COMPOUND_EXPR:
02169 return eval_subst (TREE_OPERAND (arg, 1), old0, new0, old1, new1);
02170
02171 case COND_EXPR:
02172 return fold (build (code, type,
02173 eval_subst (TREE_OPERAND (arg, 0),
02174 old0, new0, old1, new1),
02175 eval_subst (TREE_OPERAND (arg, 1),
02176 old0, new0, old1, new1),
02177 eval_subst (TREE_OPERAND (arg, 2),
02178 old0, new0, old1, new1)));
02179 default:
02180 break;
02181 }
02182
02183
02184 case '<':
02185 {
02186 tree arg0 = TREE_OPERAND (arg, 0);
02187 tree arg1 = TREE_OPERAND (arg, 1);
02188
02189
02190
02191
02192
02193 if (arg0 == old0 || operand_equal_p (arg0, old0, 0))
02194 arg0 = new0;
02195 else if (arg0 == old1 || operand_equal_p (arg0, old1, 0))
02196 arg0 = new1;
02197
02198 if (arg1 == old0 || operand_equal_p (arg1, old0, 0))
02199 arg1 = new0;
02200 else if (arg1 == old1 || operand_equal_p (arg1, old1, 0))
02201 arg1 = new1;
02202
02203 return fold (build (code, type, arg0, arg1));
02204 }
02205
02206 default:
02207 return arg;
02208 }
02209 }
02210
02211
02212
02213
02214
02215
02216
02217
02218 static tree
02219 omit_one_operand (type, result, omitted)
02220 tree type, result, omitted;
02221 {
02222 tree t = convert (type, result);
02223
02224 if (TREE_SIDE_EFFECTS (omitted))
02225 return build (COMPOUND_EXPR, type, omitted, t);
02226
02227 return non_lvalue (t);
02228 }
02229
02230
02231
02232 static tree
02233 pedantic_omit_one_operand (type, result, omitted)
02234 tree type, result, omitted;
02235 {
02236 tree t = convert (type, result);
02237
02238 if (TREE_SIDE_EFFECTS (omitted))
02239 return build (COMPOUND_EXPR, type, omitted, t);
02240
02241 return pedantic_non_lvalue (t);
02242 }
02243
02244
02245
02246
02247
02248 tree
02249 invert_truthvalue (arg)
02250 tree arg;
02251 {
02252 tree type = TREE_TYPE (arg);
02253 enum tree_code code = TREE_CODE (arg);
02254
02255 if (code == ERROR_MARK)
02256 return arg;
02257
02258
02259
02260
02261
02262 if (TREE_CODE_CLASS (code) == '<')
02263 {
02264 if (FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (arg, 0)))
02265 && !flag_unsafe_math_optimizations
02266 && code != NE_EXPR
02267 && code != EQ_EXPR)
02268 return build1 (TRUTH_NOT_EXPR, type, arg);
02269 else
02270 return build (invert_tree_comparison (code), type,
02271 TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1));
02272 }
02273
02274 switch (code)
02275 {
02276 case INTEGER_CST:
02277 return convert (type, build_int_2 (integer_zerop (arg), 0));
02278
02279 case TRUTH_AND_EXPR:
02280 return build (TRUTH_OR_EXPR, type,
02281 invert_truthvalue (TREE_OPERAND (arg, 0)),
02282 invert_truthvalue (TREE_OPERAND (arg, 1)));
02283
02284 case TRUTH_OR_EXPR:
02285 return build (TRUTH_AND_EXPR, type,
02286 invert_truthvalue (TREE_OPERAND (arg, 0)),
02287 invert_truthvalue (TREE_OPERAND (arg, 1)));
02288
02289 case TRUTH_XOR_EXPR:
02290
02291
02292
02293
02294
02295 if (TREE_CODE (TREE_OPERAND (arg, 1)) == TRUTH_NOT_EXPR)
02296 return build (TRUTH_XOR_EXPR, type, TREE_OPERAND (arg, 0),
02297 TREE_OPERAND (TREE_OPERAND (arg, 1), 0));
02298 else
02299 return build (TRUTH_XOR_EXPR, type,
02300 invert_truthvalue (TREE_OPERAND (arg, 0)),
02301 TREE_OPERAND (arg, 1));
02302
02303 case TRUTH_ANDIF_EXPR:
02304 return build (TRUTH_ORIF_EXPR, type,
02305 invert_truthvalue (TREE_OPERAND (arg, 0)),
02306 invert_truthvalue (TREE_OPERAND (arg, 1)));
02307
02308 case TRUTH_ORIF_EXPR:
02309 return build (TRUTH_ANDIF_EXPR, type,
02310 invert_truthvalue (TREE_OPERAND (arg, 0)),
02311 invert_truthvalue (TREE_OPERAND (arg, 1)));
02312
02313 case TRUTH_NOT_EXPR:
02314 return TREE_OPERAND (arg, 0);
02315
02316 case COND_EXPR:
02317 return build (COND_EXPR, type, TREE_OPERAND (arg, 0),
02318 invert_truthvalue (TREE_OPERAND (arg, 1)),
02319 invert_truthvalue (TREE_OPERAND (arg, 2)));
02320
02321 case COMPOUND_EXPR:
02322 return build (COMPOUND_EXPR, type, TREE_OPERAND (arg, 0),
02323 invert_truthvalue (TREE_OPERAND (arg, 1)));
02324
02325 case WITH_RECORD_EXPR:
02326 return build (WITH_RECORD_EXPR, type,
02327 invert_truthvalue (TREE_OPERAND (arg, 0)),
02328 TREE_OPERAND (arg, 1));
02329
02330 case NON_LVALUE_EXPR:
02331 return invert_truthvalue (TREE_OPERAND (arg, 0));
02332
02333 case NOP_EXPR:
02334 case CONVERT_EXPR:
02335 case FLOAT_EXPR:
02336 return build1 (TREE_CODE (arg), type,
02337 invert_truthvalue (TREE_OPERAND (arg, 0)));
02338
02339 case BIT_AND_EXPR:
02340 if (!integer_onep (TREE_OPERAND (arg, 1)))
02341 break;
02342 return build (EQ_EXPR, type, arg, convert (type, integer_zero_node));
02343
02344 case SAVE_EXPR:
02345 return build1 (TRUTH_NOT_EXPR, type, arg);
02346
02347 case CLEANUP_POINT_EXPR:
02348 return build1 (CLEANUP_POINT_EXPR, type,
02349 invert_truthvalue (TREE_OPERAND (arg, 0)));
02350
02351 default:
02352 break;
02353 }
02354 if (TREE_CODE (TREE_TYPE (arg)) != BOOLEAN_TYPE)
02355 abort ();
02356 return build1 (TRUTH_NOT_EXPR, type, arg);
02357 }
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368 static tree
02369 distribute_bit_expr (code, type, arg0, arg1)
02370 enum tree_code code;
02371 tree type;
02372 tree arg0, arg1;
02373 {
02374 tree common;
02375 tree left, right;
02376
02377 if (TREE_CODE (arg0) != TREE_CODE (arg1)
02378 || TREE_CODE (arg0) == code
02379 || (TREE_CODE (arg0) != BIT_AND_EXPR
02380 && TREE_CODE (arg0) != BIT_IOR_EXPR))
02381 return 0;
02382
02383 if (operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0), 0))
02384 {
02385 common = TREE_OPERAND (arg0, 0);
02386 left = TREE_OPERAND (arg0, 1);
02387 right = TREE_OPERAND (arg1, 1);
02388 }
02389 else if (operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 1), 0))
02390 {
02391 common = TREE_OPERAND (arg0, 0);
02392 left = TREE_OPERAND (arg0, 1);
02393 right = TREE_OPERAND (arg1, 0);
02394 }
02395 else if (operand_equal_p (TREE_OPERAND (arg0, 1), TREE_OPERAND (arg1, 0), 0))
02396 {
02397 common = TREE_OPERAND (arg0, 1);
02398 left = TREE_OPERAND (arg0, 0);
02399 right = TREE_OPERAND (arg1, 1);
02400 }
02401 else if (operand_equal_p (TREE_OPERAND (arg0, 1), TREE_OPERAND (arg1, 1), 0))
02402 {
02403 common = TREE_OPERAND (arg0, 1);
02404 left = TREE_OPERAND (arg0, 0);
02405 right = TREE_OPERAND (arg1, 0);
02406 }
02407 else
02408 return 0;
02409
02410 return fold (build (TREE_CODE (arg0), type, common,
02411 fold (build (code, type, left, right))));
02412 }
02413
02414
02415
02416
02417 static tree
02418 make_bit_field_ref (inner, type, bitsize, bitpos, unsignedp)
02419 tree inner;
02420 tree type;
02421 int bitsize, bitpos;
02422 int unsignedp;
02423 {
02424 tree result = build (BIT_FIELD_REF, type, inner,
02425 size_int (bitsize), bitsize_int (bitpos));
02426
02427 TREE_UNSIGNED (result) = unsignedp;
02428
02429 return result;
02430 }
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451
02452 static tree
02453 optimize_bit_field_compare (code, compare_type, lhs, rhs)
02454 enum tree_code code;
02455 tree compare_type;
02456 tree lhs, rhs;
02457 {
02458 HOST_WIDE_INT lbitpos, lbitsize, rbitpos, rbitsize, nbitpos, nbitsize;
02459 tree type = TREE_TYPE (lhs);
02460 tree signed_type, unsigned_type;
02461 int const_p = TREE_CODE (rhs) == INTEGER_CST;
02462 enum machine_mode lmode, rmode, nmode;
02463 int lunsignedp, runsignedp;
02464 int lvolatilep = 0, rvolatilep = 0;
02465 tree linner, rinner = NULL_TREE;
02466 tree mask;
02467 tree offset;
02468
02469
02470
02471
02472
02473
02474 linner = get_inner_reference (lhs, &lbitsize, &lbitpos, &offset, &lmode,
02475 &lunsignedp, &lvolatilep);
02476 if (linner == lhs || lbitsize == GET_MODE_BITSIZE (lmode) || lbitsize < 0
02477 || offset != 0 || TREE_CODE (linner) == PLACEHOLDER_EXPR)
02478 return 0;
02479
02480 if (!const_p)
02481 {
02482
02483
02484 rinner = get_inner_reference (rhs, &rbitsize, &rbitpos, &offset, &rmode,
02485 &runsignedp, &rvolatilep);
02486
02487 if (rinner == rhs || lbitpos != rbitpos || lbitsize != rbitsize
02488 || lunsignedp != runsignedp || offset != 0
02489 || TREE_CODE (rinner) == PLACEHOLDER_EXPR)
02490 return 0;
02491 }
02492
02493
02494
02495 nmode = get_best_mode (lbitsize, lbitpos,
02496 const_p ? TYPE_ALIGN (TREE_TYPE (linner))
02497 : MIN (TYPE_ALIGN (TREE_TYPE (linner)),
02498 TYPE_ALIGN (TREE_TYPE (rinner))),
02499 word_mode, lvolatilep || rvolatilep);
02500 if (nmode == VOIDmode)
02501 return 0;
02502
02503
02504
02505 signed_type = (*lang_hooks.types.type_for_mode) (nmode, 0);
02506 unsigned_type = (*lang_hooks.types.type_for_mode) (nmode, 1);
02507
02508
02509
02510
02511 nbitsize = GET_MODE_BITSIZE (nmode);
02512 nbitpos = lbitpos & ~ (nbitsize - 1);
02513 lbitpos -= nbitpos;
02514 if (nbitsize == lbitsize)
02515 return 0;
02516
02517 if (BYTES_BIG_ENDIAN)
02518 lbitpos = nbitsize - lbitsize - lbitpos;
02519
02520
02521 mask = build_int_2 (~0, ~0);
02522 TREE_TYPE (mask) = unsigned_type;
02523 force_fit_type (mask, 0);
02524 mask = convert (unsigned_type, mask);
02525 mask = const_binop (LSHIFT_EXPR, mask, size_int (nbitsize - lbitsize), 0);
02526 mask = const_binop (RSHIFT_EXPR, mask,
02527 size_int (nbitsize - lbitsize - lbitpos), 0);
02528
02529 if (! const_p)
02530
02531
02532 return build (code, compare_type,
02533 build (BIT_AND_EXPR, unsigned_type,
02534 make_bit_field_ref (linner, unsigned_type,
02535 nbitsize, nbitpos, 1),
02536 mask),
02537 build (BIT_AND_EXPR, unsigned_type,
02538 make_bit_field_ref (rinner, unsigned_type,
02539 nbitsize, nbitpos, 1),
02540 mask));
02541
02542
02543
02544
02545
02546
02547
02548
02549
02550
02551 if (lunsignedp)
02552 {
02553 if (! integer_zerop (const_binop (RSHIFT_EXPR,
02554 convert (unsigned_type, rhs),
02555 size_int (lbitsize), 0)))
02556 {
02557 warning ("comparison is always %d due to width of bit-field",
02558 code == NE_EXPR);
02559 return convert (compare_type,
02560 (code == NE_EXPR
02561 ? integer_one_node : integer_zero_node));
02562 }
02563 }
02564 else
02565 {
02566 tree tem = const_binop (RSHIFT_EXPR, convert (signed_type, rhs),
02567 size_int (lbitsize - 1), 0);
02568 if (! integer_zerop (tem) && ! integer_all_onesp (tem))
02569 {
02570 warning ("comparison is always %d due to width of bit-field",
02571 code == NE_EXPR);
02572 return convert (compare_type,
02573 (code == NE_EXPR
02574 ? integer_one_node : integer_zero_node));
02575 }
02576 }
02577
02578
02579 if (lbitsize == 1 && ! integer_zerop (rhs))
02580 {
02581 code = code == EQ_EXPR ? NE_EXPR : EQ_EXPR;
02582 rhs = convert (type, integer_zero_node);
02583 }
02584
02585
02586
02587
02588 lhs = make_bit_field_ref (linner, unsigned_type, nbitsize, nbitpos, 1);
02589 if (lvolatilep)
02590 {
02591 TREE_SIDE_EFFECTS (lhs) = 1;
02592 TREE_THIS_VOLATILE (lhs) = 1;
02593 }
02594
02595 rhs = fold (const_binop (BIT_AND_EXPR,
02596 const_binop (LSHIFT_EXPR,
02597 convert (unsigned_type, rhs),
02598 size_int (lbitpos), 0),
02599 mask, 0));
02600
02601 return build (code, compare_type,
02602 build (BIT_AND_EXPR, unsigned_type, lhs, mask),
02603 rhs);
02604 }
02605
02606
02607
02608
02609
02610
02611
02612
02613
02614
02615
02616
02617
02618
02619
02620
02621
02622
02623
02624
02625
02626
02627
02628
02629 static tree
02630 decode_field_reference (exp, pbitsize, pbitpos, pmode, punsignedp,
02631 pvolatilep, pmask, pand_mask)
02632 tree exp;
02633 HOST_WIDE_INT *pbitsize, *pbitpos;
02634 enum machine_mode *pmode;
02635 int *punsignedp, *pvolatilep;
02636 tree *pmask;
02637 tree *pand_mask;
02638 {
02639 tree and_mask = 0;
02640 tree mask, inner, offset;
02641 tree unsigned_type;
02642 unsigned int precision;
02643
02644
02645
02646
02647 if (! INTEGRAL_TYPE_P (TREE_TYPE (exp)))
02648 return 0;
02649
02650 STRIP_NOPS (exp);
02651
02652 if (TREE_CODE (exp) == BIT_AND_EXPR)
02653 {
02654 and_mask = TREE_OPERAND (exp, 1);
02655 exp = TREE_OPERAND (exp, 0);
02656 STRIP_NOPS (exp); STRIP_NOPS (and_mask);
02657 if (TREE_CODE (and_mask) != INTEGER_CST)
02658 return 0;
02659 }
02660
02661 inner = get_inner_reference (exp, pbitsize, pbitpos, &offset, pmode,
02662 punsignedp, pvolatilep);
02663 if ((inner == exp && and_mask == 0)
02664 || *pbitsize < 0 || offset != 0
02665 || TREE_CODE (inner) == PLACEHOLDER_EXPR)
02666 return 0;
02667
02668
02669 unsigned_type = (*lang_hooks.types.type_for_size) (*pbitsize, 1);
02670 precision = TYPE_PRECISION (unsigned_type);
02671
02672 mask = build_int_2 (~0, ~0);
02673 TREE_TYPE (mask) = unsigned_type;
02674 force_fit_type (mask, 0);
02675 mask = const_binop (LSHIFT_EXPR, mask, size_int (precision - *pbitsize), 0);
02676 mask = const_binop (RSHIFT_EXPR, mask, size_int (precision - *pbitsize), 0);
02677
02678
02679 if (and_mask != 0)
02680 mask = fold (build (BIT_AND_EXPR, unsigned_type,
02681 convert (unsigned_type, and_mask), mask));
02682
02683 *pmask = mask;
02684 *pand_mask = and_mask;
02685 return inner;
02686 }
02687
02688
02689
02690
02691 static int
02692 all_ones_mask_p (mask, size)
02693 tree mask;
02694 int size;
02695 {
02696 tree type = TREE_TYPE (mask);
02697 unsigned int precision = TYPE_PRECISION (type);
02698 tree tmask;
02699
02700 tmask = build_int_2 (~0, ~0);
02701 TREE_TYPE (tmask) = (*lang_hooks.types.signed_type) (type);
02702 force_fit_type (tmask, 0);
02703 return
02704 tree_int_cst_equal (mask,
02705 const_binop (RSHIFT_EXPR,
02706 const_binop (LSHIFT_EXPR, tmask,
02707 size_int (precision - size),
02708 0),
02709 size_int (precision - size), 0));
02710 }
02711
02712
02713
02714
02715
02716
02717
02718 static tree
02719 sign_bit_p (exp, val)
02720 tree exp;
02721 tree val;
02722 {
02723 unsigned HOST_WIDE_INT lo;
02724 HOST_WIDE_INT hi;
02725 int width;
02726 tree t;
02727
02728
02729 t = TREE_TYPE (exp);
02730 if (! INTEGRAL_TYPE_P (t))
02731 return NULL_TREE;
02732
02733
02734 if (TREE_CODE (val) != INTEGER_CST
02735 || TREE_CONSTANT_OVERFLOW (val))
02736 return NULL_TREE;
02737
02738 width = TYPE_PRECISION (t);
02739 if (width > HOST_BITS_PER_WIDE_INT)
02740 {
02741 hi = (unsigned HOST_WIDE_INT) 1 << (width - HOST_BITS_PER_WIDE_INT - 1);
02742 lo = 0;
02743 }
02744 else
02745 {
02746 hi = 0;
02747 lo = (unsigned HOST_WIDE_INT) 1 << (width - 1);
02748 }
02749
02750 if (TREE_INT_CST_HIGH (val) == hi && TREE_INT_CST_LOW (val) == lo)
02751 return exp;
02752
02753
02754 if (TREE_CODE (exp) == NOP_EXPR
02755 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0))) < width)
02756 return sign_bit_p (TREE_OPERAND (exp, 0), val);
02757
02758 return NULL_TREE;
02759 }
02760
02761
02762
02763
02764 static int
02765 simple_operand_p (exp)
02766 tree exp;
02767 {
02768
02769 while ((TREE_CODE (exp) == NOP_EXPR
02770 || TREE_CODE (exp) == CONVERT_EXPR)
02771 && (TYPE_MODE (TREE_TYPE (exp))
02772 == TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)))))
02773 exp = TREE_OPERAND (exp, 0);
02774
02775 return (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c'
02776 || (DECL_P (exp)
02777 && ! TREE_ADDRESSABLE (exp)
02778 && ! TREE_THIS_VOLATILE (exp)
02779 && ! DECL_NONLOCAL (exp)
02780
02781
02782
02783 && ! TREE_PUBLIC (exp)
02784 && ! DECL_EXTERNAL (exp)
02785
02786
02787 && (! TREE_STATIC (exp) || DECL_REGISTER (exp))));
02788 }
02789
02790
02791
02792
02793
02794
02795
02796
02797
02798
02799
02800
02801
02802
02803
02804
02805
02806
02807
02808
02809
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821
02822
02823
02824
02825 static tree
02826 range_binop (code, type, arg0, upper0_p, arg1, upper1_p)
02827 enum tree_code code;
02828 tree type;
02829 tree arg0, arg1;
02830 int upper0_p, upper1_p;
02831 {
02832 tree tem;
02833 int result;
02834 int sgn0, sgn1;
02835
02836
02837
02838
02839
02840
02841 if (arg0 != 0 && arg1 != 0)
02842 {
02843 tem = fold (build (code, type != 0 ? type : TREE_TYPE (arg0),
02844 arg0, convert (TREE_TYPE (arg0), arg1)));
02845 STRIP_NOPS (tem);
02846 return TREE_CODE (tem) == INTEGER_CST ? tem : 0;
02847 }
02848
02849 if (TREE_CODE_CLASS (code) != '<')
02850 return 0;
02851
02852
02853
02854
02855
02856
02857
02858 sgn0 = arg0 != 0 ? 0 : (upper0_p ? 1 : -1);
02859 sgn1 = arg1 != 0 ? 0 : (upper1_p ? 1 : -1);
02860 switch (code)
02861 {
02862 case EQ_EXPR:
02863 result = sgn0 == sgn1;
02864 break;
02865 case NE_EXPR:
02866 result = sgn0 != sgn1;
02867 break;
02868 case LT_EXPR:
02869 result = sgn0 < sgn1;
02870 break;
02871 case LE_EXPR:
02872 result = sgn0 <= sgn1;
02873 break;
02874 case GT_EXPR:
02875 result = sgn0 > sgn1;
02876 break;
02877 case GE_EXPR:
02878 result = sgn0 >= sgn1;
02879 break;
02880 default:
02881 abort ();
02882 }
02883
02884 return convert (type, result ? integer_one_node : integer_zero_node);
02885 }
02886
02887
02888
02889
02890
02891
02892
02893 static tree
02894 make_range (exp, pin_p, plow, phigh)
02895 tree exp;
02896 int *pin_p;
02897 tree *plow, *phigh;
02898 {
02899 enum tree_code code;
02900 tree arg0 = NULL_TREE, arg1 = NULL_TREE, type = NULL_TREE;
02901 tree orig_type = NULL_TREE;
02902 int in_p, n_in_p;
02903 tree low, high, n_low, n_high;
02904
02905
02906
02907
02908
02909
02910
02911 in_p = 0, low = high = convert (TREE_TYPE (exp), integer_zero_node);
02912
02913 while (1)
02914 {
02915 code = TREE_CODE (exp);
02916
02917 if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
02918 {
02919 arg0 = TREE_OPERAND (exp, 0);
02920 if (TREE_CODE_CLASS (code) == '<'
02921 || TREE_CODE_CLASS (code) == '1'
02922 || TREE_CODE_CLASS (code) == '2')
02923 type = TREE_TYPE (arg0);
02924 if (TREE_CODE_CLASS (code) == '2'
02925 || TREE_CODE_CLASS (code) == '<'
02926 || (TREE_CODE_CLASS (code) == 'e'
02927 && TREE_CODE_LENGTH (code) > 1))
02928 arg1 = TREE_OPERAND (exp, 1);
02929 }
02930
02931
02932
02933 if (type != NULL_TREE && orig_type == NULL_TREE)
02934 orig_type = type;
02935
02936 switch (code)
02937 {
02938 case TRUTH_NOT_EXPR:
02939 in_p = ! in_p, exp = arg0;
02940 continue;
02941
02942 case EQ_EXPR: case NE_EXPR:
02943 case LT_EXPR: case LE_EXPR: case GE_EXPR: case GT_EXPR:
02944
02945
02946
02947
02948
02949 if (low == 0 || high == 0
02950 || ! integer_zerop (low) || ! integer_zerop (high)
02951 || TREE_CODE (arg1) != INTEGER_CST)
02952 break;
02953
02954 switch (code)
02955 {
02956 case NE_EXPR:
02957 low = high = arg1;
02958 break;
02959 case EQ_EXPR:
02960 in_p = ! in_p, low = high = arg1;
02961 break;
02962 case GT_EXPR:
02963 low = 0, high = arg1;
02964 break;
02965 case GE_EXPR:
02966 in_p = ! in_p, low = arg1, high = 0;
02967 break;
02968 case LT_EXPR:
02969 low = arg1, high = 0;
02970 break;
02971 case LE_EXPR:
02972 in_p = ! in_p, low = 0, high = arg1;
02973 break;
02974 default:
02975 abort ();
02976 }
02977
02978 exp = arg0;
02979
02980
02981
02982
02983
02984 if (TREE_UNSIGNED (type) && (low == 0 || high == 0))
02985 {
02986 if (! merge_ranges (&n_in_p, &n_low, &n_high, in_p, low, high,
02987 1, convert (type, integer_zero_node),
02988 NULL_TREE))
02989 break;
02990
02991 in_p = n_in_p, low = n_low, high = n_high;
02992
02993
02994
02995
02996 if (high == 0 && low)
02997 {
02998 in_p = ! in_p;
02999 high = range_binop (MINUS_EXPR, NULL_TREE, low, 0,
03000 integer_one_node, 0);
03001 low = convert (type, integer_zero_node);
03002 }
03003 }
03004 continue;
03005
03006 case NEGATE_EXPR:
03007
03008 n_low = range_binop (MINUS_EXPR, type,
03009 convert (type, integer_zero_node), 0, high, 1);
03010 n_high = range_binop (MINUS_EXPR, type,
03011 convert (type, integer_zero_node), 0, low, 0);
03012 low = n_low, high = n_high;
03013 exp = arg0;
03014 continue;
03015
03016 case BIT_NOT_EXPR:
03017
03018 exp = build (MINUS_EXPR, type, negate_expr (arg0),
03019 convert (type, integer_one_node));
03020 continue;
03021
03022 case PLUS_EXPR: case MINUS_EXPR:
03023 if (TREE_CODE (arg1) != INTEGER_CST)
03024 break;
03025
03026
03027
03028
03029
03030 n_low = range_binop (code == MINUS_EXPR ? PLUS_EXPR : MINUS_EXPR,
03031 type, low, 0, arg1, 0);
03032 n_high = range_binop (code == MINUS_EXPR ? PLUS_EXPR : MINUS_EXPR,
03033 type, high, 1, arg1, 0);
03034 if ((n_low != 0 && TREE_OVERFLOW (n_low))
03035 || (n_high != 0 && TREE_OVERFLOW (n_high)))
03036 break;
03037
03038
03039
03040 if (n_low && n_high && tree_int_cst_lt (n_high, n_low))
03041 {
03042 low = range_binop (PLUS_EXPR, type, n_high, 0,
03043 integer_one_node, 0);
03044 high = range_binop (MINUS_EXPR, type, n_low, 0,
03045 integer_one_node, 0);
03046
03047
03048
03049
03050
03051 if (tree_int_cst_equal (n_low, low)
03052 && tree_int_cst_equal (n_high, high))
03053 low = high = 0;
03054 else
03055 in_p = ! in_p;
03056 }
03057 else
03058 low = n_low, high = n_high;
03059
03060 exp = arg0;
03061 continue;
03062
03063 case NOP_EXPR: case NON_LVALUE_EXPR: case CONVERT_EXPR:
03064 if (TYPE_PRECISION (type) > TYPE_PRECISION (orig_type))
03065 break;
03066
03067 if (! INTEGRAL_TYPE_P (type)
03068 || (low != 0 && ! int_fits_type_p (low, type))
03069 || (high != 0 && ! int_fits_type_p (high, type)))
03070 break;
03071
03072 n_low = low, n_high = high;
03073
03074 if (n_low != 0)
03075 n_low = convert (type, n_low);
03076
03077 if (n_high != 0)
03078 n_high = convert (type, n_high);
03079
03080
03081
03082
03083
03084
03085
03086 if (TREE_UNSIGNED (type) && ! TREE_UNSIGNED (TREE_TYPE (exp)))
03087 {
03088 tree equiv_type = (*lang_hooks.types.type_for_mode)
03089 (TYPE_MODE (type), 1);
03090 tree high_positive;
03091
03092
03093
03094
03095 high_positive
03096 = TYPE_MAX_VALUE (equiv_type) ? TYPE_MAX_VALUE (equiv_type)
03097 : TYPE_MAX_VALUE (type);
03098
03099 if (TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (exp)))
03100 high_positive = fold (build (RSHIFT_EXPR, type,
03101 convert (type, high_positive),
03102 convert (type, integer_one_node)));
03103
03104
03105
03106
03107 if (low != 0)
03108 {
03109 if (! merge_ranges (&n_in_p, &n_low, &n_high,
03110 1, n_low, n_high,
03111 1, convert (type, integer_zero_node),
03112 high_positive))
03113 break;
03114
03115 in_p = (n_in_p == in_p);
03116 }
03117 else
03118 {
03119
03120
03121 if (! merge_ranges (&n_in_p, &n_low, &n_high,
03122 0, n_low, n_high,
03123 1, convert (type, integer_zero_node),
03124 high_positive))
03125 break;
03126
03127 in_p = (in_p != n_in_p);
03128 }
03129 }
03130
03131 exp = arg0;
03132 low = n_low, high = n_high;
03133 continue;
03134
03135 default:
03136 break;
03137 }
03138
03139 break;
03140 }
03141
03142
03143 if (TREE_CODE (exp) == INTEGER_CST)
03144 {
03145 in_p = in_p == (integer_onep (range_binop (GE_EXPR, integer_type_node,
03146 exp, 0, low, 0))
03147 && integer_onep (range_binop (LE_EXPR, integer_type_node,
03148 exp, 1, high, 1)));
03149 low = high = 0;
03150 exp = 0;
03151 }
03152
03153 *pin_p = in_p, *plow = low, *phigh = high;
03154 return exp;
03155 }
03156
03157
03158
03159
03160
03161 static tree
03162 build_range_check (type, exp, in_p, low, high)
03163 tree type;
03164 tree exp;
03165 int in_p;
03166 tree low, high;
03167 {
03168 tree etype = TREE_TYPE (exp);
03169 tree value;
03170
03171 if (! in_p
03172 && (0 != (value = build_range_check (type, exp, 1, low, high))))
03173 return invert_truthvalue (value);
03174
03175 if (low == 0 && high == 0)
03176 return convert (type, integer_one_node);
03177
03178 if (low == 0)
03179 return fold (build (LE_EXPR, type, exp, high));
03180
03181 if (high == 0)
03182 return fold (build (GE_EXPR, type, exp, low));
03183
03184 if (operand_equal_p (low, high, 0))
03185 return fold (build (EQ_EXPR, type, exp, low));
03186
03187 if (integer_zerop (low))
03188 {
03189 if (! TREE_UNSIGNED (etype))
03190 {
03191 etype = (*lang_hooks.types.unsigned_type) (etype);
03192 high = convert (etype, high);
03193 exp = convert (etype, exp);
03194 }
03195 return build_range_check (type, exp, 1, 0, high);
03196 }
03197
03198
03199 if (integer_onep (low) && TREE_CODE (high) == INTEGER_CST)
03200 {
03201 unsigned HOST_WIDE_INT lo;
03202 HOST_WIDE_INT hi;
03203 int prec;
03204
03205 prec = TYPE_PRECISION (etype);
03206 if (prec <= HOST_BITS_PER_WIDE_INT)
03207 {
03208 hi = 0;
03209 lo = ((unsigned HOST_WIDE_INT) 1 << (prec - 1)) - 1;
03210 }
03211 else
03212 {
03213 hi = ((HOST_WIDE_INT) 1 << (prec - HOST_BITS_PER_WIDE_INT - 1)) - 1;
03214 lo = (unsigned HOST_WIDE_INT) -1;
03215 }
03216
03217 if (TREE_INT_CST_HIGH (high) == hi && TREE_INT_CST_LOW (high) == lo)
03218 {
03219 if (TREE_UNSIGNED (etype))
03220 {
03221 etype = (*lang_hooks.types.signed_type) (etype);
03222 exp = convert (etype, exp);
03223 }
03224 return fold (build (GT_EXPR, type, exp,
03225 convert (etype, integer_zero_node)));
03226 }
03227 }
03228
03229 if (0 != (value = const_binop (MINUS_EXPR, high, low, 0))
03230 && ! TREE_OVERFLOW (value))
03231 return build_range_check (type,
03232 fold (build (MINUS_EXPR, etype, exp, low)),
03233 1, convert (etype, integer_zero_node), value);
03234
03235 return 0;
03236 }
03237
03238
03239
03240
03241 static int
03242 merge_ranges (pin_p, plow, phigh, in0_p, low0, high0, in1_p, low1, high1)
03243 int *pin_p;
03244 tree *plow, *phigh;
03245 int in0_p, in1_p;
03246 tree low0, high0, low1, high1;
03247 {
03248 int no_overlap;
03249 int subset;
03250 int temp;
03251 tree tem;
03252 int in_p;
03253 tree low, high;
03254 int lowequal = ((low0 == 0 && low1 == 0)
03255 || integer_onep (range_binop (EQ_EXPR, integer_type_node,
03256 low0, 0, low1, 0)));
03257 int highequal = ((high0 == 0 && high1 == 0)
03258 || integer_onep (range_binop (EQ_EXPR, integer_type_node,
03259 high0, 1, high1, 1)));
03260
03261
03262
03263 if (integer_onep (range_binop (GT_EXPR, integer_type_node,
03264 low0, 0, low1, 0))
03265 || (lowequal
03266 && integer_onep (range_binop (GT_EXPR, integer_type_node,
03267 high1, 1, high0, 1))))
03268 {
03269 temp = in0_p, in0_p = in1_p, in1_p = temp;
03270 tem = low0, low0 = low1, low1 = tem;
03271 tem = high0, high0 = high1, high1 = tem;
03272 }
03273
03274
03275
03276
03277 no_overlap = integer_onep (range_binop (LT_EXPR, integer_type_node,
03278 high0, 1, low1, 0));
03279 subset = integer_onep (range_binop (LE_EXPR, integer_type_node,
03280 high1, 1, high0, 1));
03281
03282
03283
03284 if (in0_p && in1_p)
03285 {
03286
03287
03288
03289 if (no_overlap)
03290 in_p = 0, low = high = 0;
03291 else if (subset)
03292 in_p = 1, low = low1, high = high1;
03293 else
03294 in_p = 1, low = low1, high = high0;
03295 }
03296
03297 else if (in0_p && ! in1_p)
03298 {
03299
03300
03301
03302
03303
03304
03305
03306
03307 if (no_overlap)
03308 in_p = 1, low = low0, high = high0;
03309 else if (lowequal && highequal)
03310 in_p = 0, low = high = 0;
03311 else if (subset && lowequal)
03312 {
03313 in_p = 1, high = high0;
03314 low = range_binop (PLUS_EXPR, NULL_TREE, high1, 0,
03315 integer_one_node, 0);
03316 }
03317 else if (! subset || highequal)
03318 {
03319 in_p = 1, low = low0;
03320 high = range_binop (MINUS_EXPR, NULL_TREE, low1, 0,
03321 integer_one_node, 0);
03322 }
03323 else
03324 return 0;
03325 }
03326
03327 else if (! in0_p && in1_p)
03328 {
03329
03330
03331
03332
03333 if (no_overlap)
03334 in_p = 1, low = low1, high = high1;
03335 else if (subset || highequal)
03336 in_p = 0, low = high = 0;
03337 else
03338 {
03339 in_p = 1, high = high1;
03340 low = range_binop (PLUS_EXPR, NULL_TREE, high0, 1,
03341 integer_one_node, 0);
03342 }
03343 }
03344
03345 else
03346 {
03347
03348
03349
03350
03351
03352
03353 if (no_overlap)
03354 {
03355 if (integer_onep (range_binop (EQ_EXPR, integer_type_node,
03356 range_binop (PLUS_EXPR, NULL_TREE,
03357 high0, 1,
03358 integer_one_node, 1),
03359 1, low1, 0)))
03360 in_p = 0, low = low0, high = high1;
03361 else
03362 return 0;
03363 }
03364 else if (subset)
03365 in_p = 0, low = low0, high = high0;
03366 else
03367 in_p = 0, low = low0, high = high1;
03368 }
03369
03370 *pin_p = in_p, *plow = low, *phigh = high;
03371 return 1;
03372 }
03373
03374
03375
03376
03377 static tree
03378 fold_range_test (exp)
03379 tree exp;
03380 {
03381 int or_op = (TREE_CODE (exp) == TRUTH_ORIF_EXPR
03382 || TREE_CODE (exp) == TRUTH_OR_EXPR);
03383 int in0_p, in1_p, in_p;
03384 tree low0, low1, low, high0, high1, high;
03385 tree lhs = make_range (TREE_OPERAND (exp, 0), &in0_p, &low0, &high0);
03386 tree rhs = make_range (TREE_OPERAND (exp, 1), &in1_p, &low1, &high1);
03387 tree tem;
03388
03389
03390
03391 if (or_op)
03392 in0_p = ! in0_p, in1_p = ! in1_p;
03393
03394
03395
03396
03397
03398 if ((lhs == 0 || rhs == 0 || operand_equal_p (lhs, rhs, 0))
03399 && merge_ranges (&in_p, &low, &high, in0_p, low0, high0,
03400 in1_p, low1, high1)
03401 && 0 != (tem = (build_range_check (TREE_TYPE (exp),
03402 lhs != 0 ? lhs
03403 : rhs != 0 ? rhs : integer_zero_node,
03404 in_p, low, high))))
03405 return or_op ? invert_truthvalue (tem) : tem;
03406
03407
03408
03409
03410 else if (BRANCH_COST >= 2
03411 && lhs != 0 && rhs != 0
03412 && (TREE_CODE (exp) == TRUTH_ANDIF_EXPR
03413 || TREE_CODE (exp) == TRUTH_ORIF_EXPR)
03414 && operand_equal_p (lhs, rhs, 0))
03415 {
03416
03417
03418
03419 if (simple_operand_p (lhs))
03420 return build (TREE_CODE (exp) == TRUTH_ANDIF_EXPR
03421 ? TRUTH_AND_EXPR : TRUTH_OR_EXPR,
03422 TREE_TYPE (exp), TREE_OPERAND (exp, 0),
03423 TREE_OPERAND (exp, 1));
03424
03425 else if ((*lang_hooks.decls.global_bindings_p) () == 0
03426 && ! contains_placeholder_p (lhs))
03427 {
03428 tree common = save_expr (lhs);
03429
03430 if (0 != (lhs = build_range_check (TREE_TYPE (exp), common,
03431 or_op ? ! in0_p : in0_p,
03432 low0, high0))
03433 && (0 != (rhs = build_range_check (TREE_TYPE (exp), common,
03434 or_op ? ! in1_p : in1_p,
03435 low1, high1))))
03436 return build (TREE_CODE (exp) == TRUTH_ANDIF_EXPR
03437 ? TRUTH_AND_EXPR : TRUTH_OR_EXPR,
03438 TREE_TYPE (exp), lhs, rhs);
03439 }
03440 }
03441
03442 return 0;
03443 }
03444
03445
03446
03447
03448
03449
03450 static tree
03451 unextend (c, p, unsignedp, mask)
03452 tree c;
03453 int p;
03454 int unsignedp;
03455 tree mask;
03456 {
03457 tree type = TREE_TYPE (c);
03458 int modesize = GET_MODE_BITSIZE (TYPE_MODE (type));
03459 tree temp;
03460
03461 if (p == modesize || unsignedp)
03462 return c;
03463
03464
03465
03466
03467 temp = const_binop (RSHIFT_EXPR, c, size_int (p - 1), 0);
03468 temp = const_binop (BIT_AND_EXPR, temp, size_int (1), 0);
03469
03470
03471
03472
03473
03474
03475
03476 if (TREE_UNSIGNED (type))
03477 temp = convert ((*lang_hooks.types.signed_type) (type), temp);
03478
03479 temp = const_binop (LSHIFT_EXPR, temp, size_int (modesize - 1), 0);
03480 temp = const_binop (RSHIFT_EXPR, temp, size_int (modesize - p - 1), 0);
03481 if (mask != 0)
03482 temp = const_binop (BIT_AND_EXPR, temp, convert (TREE_TYPE (c), mask), 0);
03483
03484 if (TREE_UNSIGNED (type))
03485 temp = convert (type, temp);
03486
03487 return convert (type, const_binop (BIT_XOR_EXPR, c, temp, 0));
03488 }
03489
03490
03491
03492
03493
03494
03495
03496
03497
03498
03499
03500
03501
03502
03503
03504
03505
03506
03507
03508
03509
03510
03511
03512
03513
03514 static tree
03515 fold_truthop (code, truth_type, lhs, rhs)
03516 enum tree_code code;
03517 tree truth_type, lhs, rhs;
03518 {
03519
03520
03521
03522
03523
03524
03525
03526
03527
03528 enum tree_code wanted_code;
03529 enum tree_code lcode, rcode;
03530 tree ll_arg, lr_arg, rl_arg, rr_arg;
03531 tree ll_inner, lr_inner, rl_inner, rr_inner;
03532 HOST_WIDE_INT ll_bitsize, ll_bitpos, lr_bitsize, lr_bitpos;
03533 HOST_WIDE_INT rl_bitsize, rl_bitpos, rr_bitsize, rr_bitpos;
03534 HOST_WIDE_INT xll_bitpos, xlr_bitpos, xrl_bitpos, xrr_bitpos;
03535 HOST_WIDE_INT lnbitsize, lnbitpos, rnbitsize, rnbitpos;
03536 int ll_unsignedp, lr_unsignedp, rl_unsignedp, rr_unsignedp;
03537 enum machine_mode ll_mode, lr_mode, rl_mode, rr_mode;
03538 enum machine_mode lnmode, rnmode;
03539 tree ll_mask, lr_mask, rl_mask, rr_mask;
03540 tree ll_and_mask, lr_and_mask, rl_and_mask, rr_and_mask;
03541 tree l_const, r_const;
03542 tree lntype, rntype, result;
03543 int first_bit, end_bit;
03544 int volatilep;
03545
03546
03547
03548
03549
03550 if (TREE_SIDE_EFFECTS (lhs) || TREE_SIDE_EFFECTS (rhs))
03551 return 0;
03552
03553 lcode = TREE_CODE (lhs);
03554 rcode = TREE_CODE (rhs);
03555
03556 if (lcode == BIT_AND_EXPR && integer_onep (TREE_OPERAND (lhs, 1)))
03557 lcode = NE_EXPR, lhs = build (NE_EXPR, truth_type, lhs, integer_zero_node);
03558
03559 if (rcode == BIT_AND_EXPR && integer_onep (TREE_OPERAND (rhs, 1)))
03560 rcode = NE_EXPR, rhs = build (NE_EXPR, truth_type, rhs, integer_zero_node);
03561
03562 if (TREE_CODE_CLASS (lcode) != '<' || TREE_CODE_CLASS (rcode) != '<')
03563 return 0;
03564
03565 code = ((code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR)
03566 ? TRUTH_AND_EXPR : TRUTH_OR_EXPR);
03567
03568 ll_arg = TREE_OPERAND (lhs, 0);
03569 lr_arg = TREE_OPERAND (lhs, 1);
03570 rl_arg = TREE_OPERAND (rhs, 0);
03571 rr_arg = TREE_OPERAND (rhs, 1);
03572
03573
03574 if (simple_operand_p (ll_arg)
03575 && simple_operand_p (lr_arg)
03576 && !FLOAT_TYPE_P (TREE_TYPE (ll_arg)))
03577 {
03578 int compcode;
03579
03580 if (operand_equal_p (ll_arg, rl_arg, 0)
03581 && operand_equal_p (lr_arg, rr_arg, 0))
03582 {
03583 int lcompcode, rcompcode;
03584
03585 lcompcode = comparison_to_compcode (lcode);
03586 rcompcode = comparison_to_compcode (rcode);
03587 compcode = (code == TRUTH_AND_EXPR)
03588 ? lcompcode & rcompcode
03589 : lcompcode | rcompcode;
03590 }
03591 else if (operand_equal_p (ll_arg, rr_arg, 0)
03592 && operand_equal_p (lr_arg, rl_arg, 0))
03593 {
03594 int lcompcode, rcompcode;
03595
03596 rcode = swap_tree_comparison (rcode);
03597 lcompcode = comparison_to_compcode (lcode);
03598 rcompcode = comparison_to_compcode (rcode);
03599 compcode = (code == TRUTH_AND_EXPR)
03600 ? lcompcode & rcompcode
03601 : lcompcode | rcompcode;
03602 }
03603 else
03604 compcode = -1;
03605
03606 if (compcode == COMPCODE_TRUE)
03607 return convert (truth_type, integer_one_node);
03608 else if (compcode == COMPCODE_FALSE)
03609 return convert (truth_type, integer_zero_node);
03610 else if (compcode != -1)
03611 return build (compcode_to_comparison (compcode),
03612 truth_type, ll_arg, lr_arg);
03613 }
03614
03615
03616
03617
03618
03619
03620
03621 if (BRANCH_COST >= 2
03622 && ! FLOAT_TYPE_P (TREE_TYPE (rl_arg))
03623 && simple_operand_p (rl_arg)
03624 && simple_operand_p (rr_arg))
03625 {
03626
03627 if (code == TRUTH_OR_EXPR
03628 && lcode == NE_EXPR && integer_zerop (lr_arg)
03629 && rcode == NE_EXPR && integer_zerop (rr_arg)
03630 && TREE_TYPE (ll_arg) == TREE_TYPE (rl_arg))
03631 return build (NE_EXPR, truth_type,
03632 build (BIT_IOR_EXPR, TREE_TYPE (ll_arg),
03633 ll_arg, rl_arg),
03634 integer_zero_node);
03635
03636
03637 if (code == TRUTH_AND_EXPR
03638 && lcode == EQ_EXPR && integer_zerop (lr_arg)
03639 && rcode == EQ_EXPR && integer_zerop (rr_arg)
03640 && TREE_TYPE (ll_arg) == TREE_TYPE (rl_arg))
03641 return build (EQ_EXPR, truth_type,
03642 build (BIT_IOR_EXPR, TREE_TYPE (ll_arg),
03643 ll_arg, rl_arg),
03644 integer_zero_node);
03645
03646 return build (code, truth_type, lhs, rhs);
03647 }
03648
03649
03650
03651
03652 if ((lcode != EQ_EXPR && lcode != NE_EXPR)
03653 || (rcode != EQ_EXPR && rcode != NE_EXPR))
03654 return 0;
03655
03656 volatilep = 0;
03657 ll_inner = decode_field_reference (ll_arg,
03658 &ll_bitsize, &ll_bitpos, &ll_mode,
03659 &ll_unsignedp, &volatilep, &ll_mask,
03660 &ll_and_mask);
03661 lr_inner = decode_field_reference (lr_arg,
03662 &lr_bitsize, &lr_bitpos, &lr_mode,
03663 &lr_unsignedp, &volatilep, &lr_mask,
03664 &lr_and_mask);
03665 rl_inner = decode_field_reference (rl_arg,
03666 &rl_bitsize, &rl_bitpos, &rl_mode,
03667 &rl_unsignedp, &volatilep, &rl_mask,
03668 &rl_and_mask);
03669 rr_inner = decode_field_reference (rr_arg,
03670 &rr_bitsize, &rr_bitpos, &rr_mode,
03671 &rr_unsignedp, &volatilep, &rr_mask,
03672 &rr_and_mask);
03673
03674
03675
03676
03677
03678 if (volatilep || ll_inner == 0 || rl_inner == 0
03679 || ! operand_equal_p (ll_inner, rl_inner, 0))
03680 return 0;
03681
03682 if (TREE_CODE (lr_arg) == INTEGER_CST
03683 && TREE_CODE (rr_arg) == INTEGER_CST)
03684 l_const = lr_arg, r_const = rr_arg;
03685 else if (lr_inner == 0 || rr_inner == 0
03686 || ! operand_equal_p (lr_inner, rr_inner, 0))
03687 return 0;
03688 else
03689 l_const = r_const = 0;
03690
03691
03692
03693
03694
03695 wanted_code = (code == TRUTH_AND_EXPR ? EQ_EXPR : NE_EXPR);
03696 if (lcode != wanted_code)
03697 {
03698 if (l_const && integer_zerop (l_const) && integer_pow2p (ll_mask))
03699 {
03700
03701
03702
03703 ll_unsignedp = 1;
03704 l_const = ll_mask;
03705 }
03706 else
03707 return 0;
03708 }
03709
03710
03711 if (rcode != wanted_code)
03712 {
03713 if (r_const && integer_zerop (r_const) && integer_pow2p (rl_mask))
03714 {
03715 rl_unsignedp = 1;
03716 r_const = rl_mask;
03717 }
03718 else
03719 return 0;
03720 }
03721
03722
03723
03724 if (! (*lang_hooks.can_use_bit_fields_p) ())
03725 return 0;
03726
03727
03728
03729
03730 first_bit = MIN (ll_bitpos, rl_bitpos);
03731 end_bit = MAX (ll_bitpos + ll_bitsize, rl_bitpos + rl_bitsize);
03732 lnmode = get_best_mode (end_bit - first_bit, first_bit,
03733 TYPE_ALIGN (TREE_TYPE (ll_inner)), word_mode,
03734 volatilep);
03735 if (lnmode == VOIDmode)
03736 return 0;
03737
03738 lnbitsize = GET_MODE_BITSIZE (lnmode);
03739 lnbitpos = first_bit & ~ (lnbitsize - 1);
03740 lntype = (*lang_hooks.types.type_for_size) (lnbitsize, 1);
03741 xll_bitpos = ll_bitpos - lnbitpos, xrl_bitpos = rl_bitpos - lnbitpos;
03742
03743 if (BYTES_BIG_ENDIAN)
03744 {
03745 xll_bitpos = lnbitsize - xll_bitpos - ll_bitsize;
03746 xrl_bitpos = lnbitsize - xrl_bitpos - rl_bitsize;
03747 }
03748
03749 ll_mask = const_binop (LSHIFT_EXPR, convert (lntype, ll_mask),
03750 size_int (xll_bitpos), 0);
03751 rl_mask = const_binop (LSHIFT_EXPR, convert (lntype, rl_mask),
03752 size_int (xrl_bitpos), 0);
03753
03754 if (l_const)
03755 {
03756 l_const = convert (lntype, l_const);
03757 l_const = unextend (l_const, ll_bitsize, ll_unsignedp, ll_and_mask);
03758 l_const = const_binop (LSHIFT_EXPR, l_const, size_int (xll_bitpos), 0);
03759 if (! integer_zerop (const_binop (BIT_AND_EXPR, l_const,
03760 fold (build1 (BIT_NOT_EXPR,
03761 lntype, ll_mask)),
03762 0)))
03763 {
03764 warning ("comparison is always %d", wanted_code == NE_EXPR);
03765
03766 return convert (truth_type,
03767 wanted_code == NE_EXPR
03768 ? integer_one_node : integer_zero_node);
03769 }
03770 }
03771 if (r_const)
03772 {
03773 r_const = convert (lntype, r_const);
03774 r_const = unextend (r_const, rl_bitsize, rl_unsignedp, rl_and_mask);
03775 r_const = const_binop (LSHIFT_EXPR, r_const, size_int (xrl_bitpos), 0);
03776 if (! integer_zerop (const_binop (BIT_AND_EXPR, r_const,
03777 fold (build1 (BIT_NOT_EXPR,
03778 lntype, rl_mask)),
03779 0)))
03780 {
03781 warning ("comparison is always %d", wanted_code == NE_EXPR);
03782
03783 return convert (truth_type,
03784 wanted_code == NE_EXPR
03785 ? integer_one_node : integer_zero_node);
03786 }
03787 }
03788
03789
03790
03791
03792 if (l_const == 0)
03793 {
03794 if (ll_bitsize != lr_bitsize || rl_bitsize != rr_bitsize
03795 || ll_unsignedp != lr_unsignedp || rl_unsignedp != rr_unsignedp
03796
03797
03798 || ll_bitpos - rl_bitpos != lr_bitpos - rr_bitpos)
03799 return 0;
03800
03801 first_bit = MIN (lr_bitpos, rr_bitpos);
03802 end_bit = MAX (lr_bitpos + lr_bitsize, rr_bitpos + rr_bitsize);
03803 rnmode = get_best_mode (end_bit - first_bit, first_bit,
03804 TYPE_ALIGN (TREE_TYPE (lr_inner)), word_mode,
03805 volatilep);
03806 if (rnmode == VOIDmode)
03807 return 0;
03808
03809 rnbitsize = GET_MODE_BITSIZE (rnmode);
03810 rnbitpos = first_bit & ~ (rnbitsize - 1);
03811 rntype = (*lang_hooks.types.type_for_size) (rnbitsize, 1);
03812 xlr_bitpos = lr_bitpos - rnbitpos, xrr_bitpos = rr_bitpos - rnbitpos;
03813
03814 if (BYTES_BIG_ENDIAN)
03815 {
03816 xlr_bitpos = rnbitsize - xlr_bitpos - lr_bitsize;
03817 xrr_bitpos = rnbitsize - xrr_bitpos - rr_bitsize;
03818 }
03819
03820 lr_mask = const_binop (LSHIFT_EXPR, convert (rntype, lr_mask),
03821 size_int (xlr_bitpos), 0);
03822 rr_mask = const_binop (LSHIFT_EXPR, convert (rntype, rr_mask),
03823 size_int (xrr_bitpos), 0);
03824
03825
03826
03827
03828
03829
03830 ll_mask = const_binop (BIT_IOR_EXPR, ll_mask, rl_mask, 0);
03831 lr_mask = const_binop (BIT_IOR_EXPR, lr_mask, rr_mask, 0);
03832 if (lnbitsize == rnbitsize && xll_bitpos == xlr_bitpos)
03833 {
03834 lhs = make_bit_field_ref (ll_inner, lntype, lnbitsize, lnbitpos,
03835 ll_unsignedp || rl_unsignedp);
03836 if (! all_ones_mask_p (ll_mask, lnbitsize))
03837 lhs = build (BIT_AND_EXPR, lntype, lhs, ll_mask);
03838
03839 rhs = make_bit_field_ref (lr_inner, rntype, rnbitsize, rnbitpos,
03840 lr_unsignedp || rr_unsignedp);
03841 if (! all_ones_mask_p (lr_mask, rnbitsize))
03842 rhs = build (BIT_AND_EXPR, rntype, rhs, lr_mask);
03843
03844 return build (wanted_code, truth_type, lhs, rhs);
03845 }
03846
03847
03848
03849
03850
03851
03852
03853
03854 if ((ll_bitsize + ll_bitpos == rl_bitpos
03855 && lr_bitsize + lr_bitpos == rr_bitpos)
03856 || (ll_bitpos == rl_bitpos + rl_bitsize
03857 && lr_bitpos == rr_bitpos + rr_bitsize))
03858 {
03859 tree type;
03860
03861 lhs = make_bit_field_ref (ll_inner, lntype, ll_bitsize + rl_bitsize,
03862 MIN (ll_bitpos, rl_bitpos), ll_unsignedp);
03863 rhs = make_bit_field_ref (lr_inner, rntype, lr_bitsize + rr_bitsize,
03864 MIN (lr_bitpos, rr_bitpos), lr_unsignedp);
03865
03866 ll_mask = const_binop (RSHIFT_EXPR, ll_mask,
03867 size_int (MIN (xll_bitpos, xrl_bitpos)), 0);
03868 lr_mask = const_binop (RSHIFT_EXPR, lr_mask,
03869 size_int (MIN (xlr_bitpos, xrr_bitpos)), 0);
03870
03871
03872 type = lntype;
03873 if (lntype != rntype)
03874 {
03875 if (lnbitsize > rnbitsize)
03876 {
03877 lhs = convert (rntype, lhs);
03878 ll_mask = convert (rntype, ll_mask);
03879 type = rntype;
03880 }
03881 else if (lnbitsize < rnbitsize)
03882 {
03883 rhs = convert (lntype, rhs);
03884 lr_mask = convert (lntype, lr_mask);
03885 type = lntype;
03886 }
03887 }
03888
03889 if (! all_ones_mask_p (ll_mask, ll_bitsize + rl_bitsize))
03890 lhs = build (BIT_AND_EXPR, type, lhs, ll_mask);
03891
03892 if (! all_ones_mask_p (lr_mask, lr_bitsize + rr_bitsize))
03893 rhs = build (BIT_AND_EXPR, type, rhs, lr_mask);
03894
03895 return build (wanted_code, truth_type, lhs, rhs);
03896 }
03897
03898 return 0;
03899 }
03900
03901
03902
03903
03904
03905 result = const_binop (BIT_AND_EXPR, ll_mask, rl_mask, 0);
03906 if (! integer_zerop (result)
03907 && simple_cst_equal (const_binop (BIT_AND_EXPR, result, l_const, 0),
03908 const_binop (BIT_AND_EXPR, result, r_const, 0)) != 1)
03909 {
03910 if (wanted_code == NE_EXPR)
03911 {
03912 warning ("`or' of unmatched not-equal tests is always 1");
03913 return convert (truth_type, integer_one_node);
03914 }
03915 else
03916 {
03917 warning ("`and' of mutually exclusive equal-tests is always 0");
03918 return convert (truth_type, integer_zero_node);
03919 }
03920 }
03921
03922
03923
03924
03925
03926 result = make_bit_field_ref (ll_inner, lntype, lnbitsize, lnbitpos,
03927 ll_unsignedp || rl_unsignedp);
03928
03929 ll_mask = const_binop (BIT_IOR_EXPR, ll_mask, rl_mask, 0);
03930 if (! all_ones_mask_p (ll_mask, lnbitsize))
03931 result = build (BIT_AND_EXPR, lntype, result, ll_mask);
03932
03933 return build (wanted_code, truth_type, result,
03934 const_binop (BIT_IOR_EXPR, l_const, r_const, 0));
03935 }
03936
03937
03938
03939
03940 static tree
03941 optimize_minmax_comparison (t)
03942 tree t;
03943 {
03944 tree type = TREE_TYPE (t);
03945 tree arg0 = TREE_OPERAND (t, 0);
03946 enum tree_code op_code;
03947 tree comp_const = TREE_OPERAND (t, 1);
03948 tree minmax_const;
03949 int consts_equal, consts_lt;
03950 tree inner;
03951
03952 STRIP_SIGN_NOPS (arg0);
03953
03954 op_code = TREE_CODE (arg0);
03955 minmax_const = TREE_OPERAND (arg0, 1);
03956 consts_equal = tree_int_cst_equal (minmax_const, comp_const);
03957 consts_lt = tree_int_cst_lt (minmax_const, comp_const);
03958 inner = TREE_OPERAND (arg0, 0);
03959
03960
03961 if ((op_code != MIN_EXPR && op_code != MAX_EXPR)
03962 || TREE_CODE (comp_const) != INTEGER_CST
03963 || TREE_CONSTANT_OVERFLOW (comp_const)
03964 || TREE_CODE (minmax_const) != INTEGER_CST
03965 || TREE_CONSTANT_OVERFLOW (minmax_const))
03966 return t;
03967
03968
03969
03970
03971 switch (TREE_CODE (t))
03972 {
03973 case NE_EXPR: case LT_EXPR: case LE_EXPR:
03974 return
03975 invert_truthvalue (optimize_minmax_comparison (invert_truthvalue (t)));
03976
03977 case GE_EXPR:
03978 return
03979 fold (build (TRUTH_ORIF_EXPR, type,
03980 optimize_minmax_comparison
03981 (build (EQ_EXPR, type, arg0, comp_const)),
03982 optimize_minmax_comparison
03983 (build (GT_EXPR, type, arg0, comp_const))));
03984
03985 case EQ_EXPR:
03986 if (op_code == MAX_EXPR && consts_equal)
03987
03988 return fold (build (LE_EXPR, type, inner, comp_const));
03989
03990 else if (op_code == MAX_EXPR && consts_lt)
03991
03992 return fold (build (EQ_EXPR, type, inner, comp_const));
03993
03994 else if (op_code == MAX_EXPR)
03995
03996 return omit_one_operand (type, integer_zero_node, inner);
03997
03998 else if (consts_equal)
03999
04000 return fold (build (GE_EXPR, type, inner, comp_const));
04001
04002 else if (consts_lt)
04003
04004 return omit_one_operand (type, integer_zero_node, inner);
04005
04006 else
04007
04008 return fold (build (EQ_EXPR, type, inner, comp_const));
04009
04010 case GT_EXPR:
04011 if (op_code == MAX_EXPR && (consts_equal || consts_lt))
04012
04013
04014 return fold (build (GT_EXPR, type, inner, comp_const));
04015
04016 else if (op_code == MAX_EXPR)
04017
04018 return omit_one_operand (type, integer_one_node, inner);
04019
04020 else if (op_code == MIN_EXPR && (consts_equal || consts_lt))
04021
04022
04023 return omit_one_operand (type, integer_zero_node, inner);
04024
04025 else
04026
04027 return fold (build (GT_EXPR, type, inner, comp_const));
04028
04029 default:
04030 return t;
04031 }
04032 }
04033
04034
04035
04036
04037
04038
04039
04040
04041
04042
04043
04044
04045
04046
04047
04048
04049
04050
04051
04052 static tree
04053 extract_muldiv (t, c, code, wide_type)
04054 tree t;
04055 tree c;
04056 enum tree_code code;
04057 tree wide_type;
04058 {
04059
04060
04061
04062
04063
04064 static int depth;
04065 tree ret;
04066
04067 if (depth > 3)
04068 return NULL;
04069
04070 depth++;
04071 ret = extract_muldiv_1 (t, c, code, wide_type);
04072 depth--;
04073
04074 return ret;
04075 }
04076
04077 static tree
04078 extract_muldiv_1 (t, c, code, wide_type)
04079 tree t;
04080 tree c;
04081 enum tree_code code;
04082 tree wide_type;
04083 {
04084 tree type = TREE_TYPE (t);
04085 enum tree_code tcode = TREE_CODE (t);
04086 tree ctype = (wide_type != 0 && (GET_MODE_SIZE (TYPE_MODE (wide_type))
04087 > GET_MODE_SIZE (TYPE_MODE (type)))
04088 ? wide_type : type);
04089 tree t1, t2;
04090 int same_p = tcode == code;
04091 tree op0 = NULL_TREE, op1 = NULL_TREE;
04092
04093
04094 if (integer_zerop (c))
04095 return NULL_TREE;
04096
04097 if (TREE_CODE_CLASS (tcode) == '1')
04098 op0 = TREE_OPERAND (t, 0);
04099
04100 if (TREE_CODE_CLASS (tcode) == '2')
04101 op0 = TREE_OPERAND (t, 0), op1 = TREE_OPERAND (t, 1);
04102
04103
04104
04105 switch (tcode)
04106 {
04107 case INTEGER_CST:
04108
04109
04110 if (code == MULT_EXPR
04111 || integer_zerop (const_binop (TRUNC_MOD_EXPR, t, c, 0)))
04112 return const_binop (code, convert (ctype, t), convert (ctype, c), 0);
04113 break;
04114
04115 #ifndef KEY
04116
04117 case CONVERT_EXPR: case NON_LVALUE_EXPR: case NOP_EXPR:
04118
04119 if ((TREE_CODE_CLASS (TREE_CODE (op0)) == '<'
04120 || TREE_CODE_CLASS (TREE_CODE (op0)) == '1'
04121 || TREE_CODE_CLASS (TREE_CODE (op0)) == '2'
04122 || TREE_CODE_CLASS (TREE_CODE (op0)) == 'e')
04123
04124
04125 && ((TREE_UNSIGNED (TREE_TYPE (op0))
04126 && ! (TREE_CODE (TREE_TYPE (op0)) == INTEGER_TYPE
04127 && TYPE_IS_SIZETYPE (TREE_TYPE (op0)))
04128 && (GET_MODE_SIZE (TYPE_MODE (ctype))
04129 > GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0)))))
04130
04131
04132 || (GET_MODE_SIZE (TYPE_MODE (ctype))
04133 < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0))))
04134
04135
04136 || (code != MULT_EXPR
04137 && (TREE_UNSIGNED (ctype)
04138 != TREE_UNSIGNED (TREE_TYPE (op0))))))
04139 break;
04140
04141
04142
04143
04144 if (0 != (t1 = extract_muldiv (op0, convert (TREE_TYPE (op0), c), code,
04145 code == MULT_EXPR ? ctype : NULL_TREE)))
04146 return t1;
04147 break;
04148 #endif // !KEY
04149
04150 case NEGATE_EXPR: case ABS_EXPR:
04151 if ((t1 = extract_muldiv (op0, c, code, wide_type)) != 0)
04152 return fold (build1 (tcode, ctype, convert (ctype, t1)));
04153 break;
04154
04155 case MIN_EXPR: case MAX_EXPR:
04156
04157
04158 if (TREE_UNSIGNED (ctype) != TREE_UNSIGNED (type))
04159 break;
04160
04161
04162 if ((t1 = extract_muldiv (op0, c, code, wide_type)) != 0
04163 && (t2 = extract_muldiv (op1, c, code, wide_type)) != 0)
04164 {
04165 if (tree_int_cst_sgn (c) < 0)
04166 tcode = (tcode == MIN_EXPR ? MAX_EXPR : MIN_EXPR);
04167
04168 return fold (build (tcode, ctype, convert (ctype, t1),
04169 convert (ctype, t2)));
04170 }
04171 break;
04172
04173 case WITH_RECORD_EXPR:
04174 if ((t1 = extract_muldiv (TREE_OPERAND (t, 0), c, code, wide_type)) != 0)
04175 return build (WITH_RECORD_EXPR, TREE_TYPE (t1), t1,
04176 TREE_OPERAND (t, 1));
04177 break;
04178
04179 case LSHIFT_EXPR: case RSHIFT_EXPR:
04180
04181
04182
04183 if (TREE_CODE (op1) == INTEGER_CST
04184
04185
04186 && TYPE_PRECISION (TREE_TYPE (size_one_node)) > TREE_INT_CST_LOW (op1)
04187 && TREE_INT_CST_HIGH (op1) == 0
04188 && 0 != (t1 = convert (ctype,
04189 const_binop (LSHIFT_EXPR, size_one_node,
04190 op1, 0)))
04191 && ! TREE_OVERFLOW (t1))
04192 return extract_muldiv (build (tcode == LSHIFT_EXPR
04193 ? MULT_EXPR : FLOOR_DIV_EXPR,
04194 ctype, convert (ctype, op0), t1),
04195 c, code, wide_type);
04196 break;
04197
04198 case PLUS_EXPR: case MINUS_EXPR:
04199
04200
04201
04202
04203 t1 = extract_muldiv (op0, c, code, wide_type);
04204 t2 = extract_muldiv (op1, c, code, wide_type);
04205 if (t1 != 0 && t2 != 0
04206 && (code == MULT_EXPR
04207
04208
04209 || (multiple_of_p (ctype, op0, c)
04210 && multiple_of_p (ctype, op1, c))))
04211 return fold (build (tcode, ctype, convert (ctype, t1),
04212 convert (ctype, t2)));
04213
04214
04215
04216 if (tcode == MINUS_EXPR)
04217 tcode = PLUS_EXPR, op1 = negate_expr (op1);
04218
04219 if (TREE_CODE (op1) != INTEGER_CST)
04220 break;
04221
04222
04223
04224
04225 if (tree_int_cst_sgn (op1) < 0 || tree_int_cst_sgn (c) < 0)
04226 {
04227 if (code == CEIL_DIV_EXPR)
04228 code = FLOOR_DIV_EXPR;
04229 else if (code == FLOOR_DIV_EXPR)
04230 code = CEIL_DIV_EXPR;
04231 else if (code != MULT_EXPR
04232 && code != CEIL_MOD_EXPR && code != FLOOR_MOD_EXPR)
04233 break;
04234 }
04235
04236
04237
04238 if (code == MULT_EXPR
04239 || integer_zerop (const_binop (TRUNC_MOD_EXPR, op1, c, 0)))
04240 {
04241 op1 = const_binop (code, convert (ctype, op1), convert (ctype, c), 0);
04242 if (op1 == 0 || TREE_OVERFLOW (op1))
04243 break;
04244 }
04245 else
04246 break;
04247
04248
04249
04250
04251 if (TREE_UNSIGNED (ctype)
04252 && ! (TREE_CODE (ctype) == INTEGER_TYPE && TYPE_IS_SIZETYPE (ctype))
04253 && ctype != type)
04254 break;
04255
04256
04257
04258 if (t1 != 0 && (TREE_CODE (t1) != code || code == MULT_EXPR))
04259 return fold (build (tcode, ctype, convert (ctype, t1), op1));
04260
04261
04262
04263
04264 if (code == MULT_EXPR)
04265 return fold (build (tcode, ctype, fold (build (code, ctype,
04266 convert (ctype, op0),
04267 convert (ctype, c))),
04268 op1));
04269
04270 break;
04271
04272 case MULT_EXPR:
04273
04274
04275 if ((code == TRUNC_MOD_EXPR || code == CEIL_MOD_EXPR
04276 || code == FLOOR_MOD_EXPR || code == ROUND_MOD_EXPR)
04277 && TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST
04278 && integer_zerop (const_binop (TRUNC_MOD_EXPR, op1, c, 0)))
04279 return omit_one_operand (type, integer_zero_node, op0);
04280
04281
04282
04283 case TRUNC_DIV_EXPR: case CEIL_DIV_EXPR: case FLOOR_DIV_EXPR:
04284 case ROUND_DIV_EXPR: case EXACT_DIV_EXPR:
04285
04286
04287
04288 if (same_p
04289 && (t1 = extract_muldiv (op0, c, code, wide_type)) != 0)
04290 return fold (build (tcode, ctype, convert (ctype, t1),
04291 convert (ctype, op1)));
04292 else if (tcode == MULT_EXPR && code == MULT_EXPR
04293 && (t1 = extract_muldiv (op1, c, code, wide_type)) != 0)
04294 return fold (build (tcode, ctype, convert (ctype, op0),
04295 convert (ctype, t1)));
04296 else if (TREE_CODE (op1) != INTEGER_CST)
04297 return 0;
04298
04299
04300
04301 if (tcode == code
04302 && 0 != (t1 = const_binop (MULT_EXPR, convert (ctype, op1),
04303 convert (ctype, c), 0))
04304 && ! TREE_OVERFLOW (t1))
04305 return fold (build (tcode, ctype, convert (ctype, op0), t1));
04306
04307 #ifdef KEY
04308
04309 if (TREE_CODE(ctype) == INTEGER_TYPE &&
04310 code == TRUNC_DIV_EXPR &&
04311 tcode == MULT_EXPR)
04312 return 0;
04313 #endif
04314
04315
04316
04317
04318
04319
04320
04321
04322
04323 if ((! TREE_UNSIGNED (ctype)
04324 #ifndef KEY
04325 || (TREE_CODE (ctype) == INTEGER_TYPE && TYPE_IS_SIZETYPE (ctype))
04326 #else
04327 || (TYPE_IS_SIZETYPE (ctype))
04328 #endif
04329 )
04330 && ((code == MULT_EXPR && tcode == EXACT_DIV_EXPR)
04331 || (tcode == MULT_EXPR
04332 #ifdef KEY
04333
04334 && code != MULT_EXPR
04335 #endif
04336 && code != TRUNC_MOD_EXPR && code != CEIL_MOD_EXPR
04337 && code != FLOOR_MOD_EXPR && code != ROUND_MOD_EXPR)))
04338 {
04339 if (integer_zerop (const_binop (TRUNC_MOD_EXPR, op1, c, 0)))
04340 return fold (build (tcode, ctype, convert (ctype, op0),
04341 convert (ctype,
04342 const_binop (TRUNC_DIV_EXPR,
04343 op1, c, 0))));
04344 else if (integer_zerop (const_binop (TRUNC_MOD_EXPR, c, op1, 0)))
04345 return fold (build (code, ctype, convert (ctype, op0),
04346 convert (ctype,
04347 const_binop (TRUNC_DIV_EXPR,
04348 c, op1, 0))));
04349 }
04350 break;
04351
04352 default:
04353 break;
04354 }
04355
04356 return 0;
04357 }
04358
04359
04360
04361
04362
04363 static tree
04364 strip_compound_expr (t, s)
04365 tree t;
04366 tree s;
04367 {
04368 enum tree_code code = TREE_CODE (t);
04369
04370
04371 if (code == COMPOUND_EXPR && TREE_CODE (TREE_OPERAND (t, 0)) == CONVERT_EXPR
04372 && TREE_OPERAND (TREE_OPERAND (t, 0), 0) == s)
04373 return TREE_OPERAND (t, 1);
04374
04375
04376
04377 else if (code == COND_EXPR)
04378 {
04379 TREE_OPERAND (t, 0) = strip_compound_expr (TREE_OPERAND (t, 0), s);
04380 TREE_OPERAND (t, 1) = strip_compound_expr (TREE_OPERAND (t, 1), s);
04381 TREE_OPERAND (t, 2) = strip_compound_expr (TREE_OPERAND (t, 2), s);
04382 }
04383 else if (TREE_CODE_CLASS (code) == '1')
04384 TREE_OPERAND (t, 0) = strip_compound_expr (TREE_OPERAND (t, 0), s);
04385 else if (TREE_CODE_CLASS (code) == '<'
04386 || TREE_CODE_CLASS (code) == '2')
04387 {
04388 TREE_OPERAND (t, 0) = strip_compound_expr (TREE_OPERAND (t, 0), s);
04389 TREE_OPERAND (t, 1) = strip_compound_expr (TREE_OPERAND (t, 1), s);
04390 }
04391
04392 return t;
04393 }
04394
04395
04396
04397
04398 static tree
04399 constant_boolean_node (value, type)
04400 int value;
04401 tree type;
04402 {
04403 if (type == integer_type_node)
04404 return value ? integer_one_node : integer_zero_node;
04405 else if (TREE_CODE (type) == BOOLEAN_TYPE)
04406 return (*lang_hooks.truthvalue_conversion) (value ? integer_one_node :
04407 integer_zero_node);
04408 else
04409 {
04410 tree t = build_int_2 (value, 0);
04411
04412 TREE_TYPE (t) = type;
04413 return t;
04414 }
04415 }
04416
04417
04418
04419
04420
04421 static int
04422 count_cond (expr, lim)
04423 tree expr;
04424 int lim;
04425 {
04426 int ctrue, cfalse;
04427
04428 if (TREE_CODE (expr) != COND_EXPR)
04429 return 0;
04430 else if (lim <= 0)
04431 return 0;
04432
04433 ctrue = count_cond (TREE_OPERAND (expr, 1), lim - 1);
04434 cfalse = count_cond (TREE_OPERAND (expr, 2), lim - 1 - ctrue);
04435 return MIN (lim, 1 + ctrue + cfalse);
04436 }
04437
04438
04439
04440
04441
04442
04443
04444
04445
04446 static tree
04447 fold_binary_op_with_conditional_arg (code, type, cond, arg, cond_first_p)
04448 enum tree_code code;
04449 tree type;
04450 tree cond;
04451 tree arg;
04452 int cond_first_p;
04453 {
04454 tree test, true_value, false_value;
04455 tree lhs = NULL_TREE;
04456 tree rhs = NULL_TREE;
04457
04458
04459
04460
04461
04462
04463
04464
04465 tree *true_lhs;
04466 tree *true_rhs;
04467 tree *false_lhs;
04468 tree *false_rhs;
04469
04470
04471 enum tree_code lhs_code = code;
04472 enum tree_code rhs_code = code;
04473
04474 tree lhs_type = type;
04475 tree rhs_type = type;
04476 int save = 0;
04477
04478 if (cond_first_p)
04479 {
04480 true_rhs = false_rhs = &arg;
04481 true_lhs = &true_value;
04482 false_lhs = &false_value;
04483 }
04484 else
04485 {
04486 true_lhs = false_lhs = &arg;
04487 true_rhs = &true_value;
04488 false_rhs = &false_value;
04489 }
04490
04491 if (TREE_CODE (cond) == COND_EXPR)
04492 {
04493 test = TREE_OPERAND (cond, 0);
04494 true_value = TREE_OPERAND (cond, 1);
04495 false_value = TREE_OPERAND (cond, 2);
04496
04497
04498
04499
04500 if (VOID_TYPE_P (TREE_TYPE (true_value)))
04501 {
04502 if (! cond_first_p)
04503 {
04504 lhs_code = COMPOUND_EXPR;
04505 lhs_type = void_type_node;
04506 }
04507 else
04508 lhs = true_value;
04509 }
04510 if (VOID_TYPE_P (TREE_TYPE (false_value)))
04511 {
04512 if (! cond_first_p)
04513 {
04514 rhs_code = COMPOUND_EXPR;
04515 rhs_type = void_type_node;
04516 }
04517 else
04518 rhs = false_value;
04519 }
04520 }
04521 else
04522 {
04523 tree testtype = TREE_TYPE (cond);
04524 test = cond;
04525 true_value = convert (testtype, integer_one_node);
04526 false_value = convert (testtype, integer_zero_node);
04527 }
04528
04529
04530
04531
04532
04533
04534
04535
04536
04537
04538
04539
04540
04541
04542
04543 if (TREE_CODE (arg) == SAVE_EXPR)
04544 save = 1;
04545 else if (lhs == 0 && rhs == 0
04546 && !TREE_CONSTANT (arg)
04547 && (*lang_hooks.decls.global_bindings_p) () == 0
04548 && ((TREE_CODE (arg) != VAR_DECL && TREE_CODE (arg) != PARM_DECL)
04549 || TREE_SIDE_EFFECTS (arg)))
04550 {
04551 if (TREE_CODE (true_value) != COND_EXPR)
04552 lhs = fold (build (lhs_code, lhs_type, *true_lhs, *true_rhs));
04553
04554 if (TREE_CODE (false_value) != COND_EXPR)
04555 rhs = fold (build (rhs_code, rhs_type, *false_lhs, *false_rhs));
04556
04557 if ((lhs == 0 || ! TREE_CONSTANT (lhs))
04558 && (rhs == 0 || !TREE_CONSTANT (rhs)))
04559 {
04560 arg = save_expr (arg);
04561 lhs = rhs = 0;
04562 save = 1;
04563 }
04564 }
04565
04566 if (lhs == 0)
04567 lhs = fold (build (lhs_code, lhs_type, *true_lhs, *true_rhs));
04568 if (rhs == 0)
04569 rhs = fold (build (rhs_code, rhs_type, *false_lhs, *false_rhs));
04570
04571 test = fold (build (COND_EXPR, type, test, lhs, rhs));
04572
04573 if (save)
04574 return build (COMPOUND_EXPR, type,
04575 convert (void_type_node, arg),
04576 strip_compound_expr (test, arg));
04577 else
04578 return convert (type, test);
04579 }
04580
04581
04582
04583
04584
04585
04586
04587
04588
04589
04590
04591
04592
04593
04594 static bool
04595 fold_real_zero_addition_p (type, addend, negate)
04596 tree type, addend;
04597 int negate;
04598 {
04599 if (!real_zerop (addend))
04600 return false;
04601
04602
04603 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (type)))
04604 return true;
04605
04606
04607 if (TREE_CODE (addend) == REAL_CST
04608 && REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (addend)))
04609 negate = !negate;
04610
04611
04612
04613
04614
04615 return negate && !HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (type));
04616 }
04617
04618
04619
04620
04621
04622
04623
04624
04625
04626
04627 #ifdef ENABLE_FOLD_CHECKING
04628 # define fold(x) fold_1 (x)
04629 static tree fold_1 PARAMS ((tree));
04630 static
04631 #endif
04632 tree
04633 fold (expr)
04634 tree expr;
04635 {
04636 tree t = expr, orig_t;
04637 tree t1 = NULL_TREE;
04638 tree tem;
04639 tree type = TREE_TYPE (expr);
04640 tree arg0 = NULL_TREE, arg1 = NULL_TREE;
04641 enum tree_code code = TREE_CODE (t);
04642 int kind = TREE_CODE_CLASS (code);
04643 int invert;
04644
04645
04646 int wins = 1;
04647
04648
04649
04650 if (code == RTL_EXPR || (code == SAVE_EXPR && SAVE_EXPR_RTL (t) != 0))
04651 return t;
04652
04653
04654 if (kind == 'c')
04655 return t;
04656
04657 #ifdef MAX_INTEGER_COMPUTATION_MODE
04658 check_max_integer_computation_mode (expr);
04659 #endif
04660 orig_t = t;
04661
04662 if (code == NOP_EXPR || code == FLOAT_EXPR || code == CONVERT_EXPR)
04663 {
04664 tree subop;
04665
04666
04667 arg0 = TREE_OPERAND (t, 0);
04668
04669
04670 if (arg0 != 0)
04671 STRIP_SIGN_NOPS (arg0);
04672
04673 if (arg0 != 0 && TREE_CODE (arg0) == COMPLEX_CST)
04674 subop = TREE_REALPART (arg0);
04675 else
04676 subop = arg0;
04677
04678 if (subop != 0 && TREE_CODE (subop) != INTEGER_CST
04679 && TREE_CODE (subop) != REAL_CST
04680 )
04681
04682
04683
04684 wins = 0;
04685 }
04686 else if (IS_EXPR_CODE_CLASS (kind) || kind == 'r')
04687 {
04688 int len = first_rtl_op (code);
04689 int i;
04690 for (i = 0; i < len; i++)
04691 {
04692 tree op = TREE_OPERAND (t, i);
04693 tree subop;
04694
04695 if (op == 0)
04696 continue;
04697
04698 if (kind == '<' || code == RSHIFT_EXPR)
04699 {
04700
04701
04702 STRIP_SIGN_NOPS (op);
04703 }
04704 else
04705
04706 STRIP_NOPS (op);
04707
04708 if (TREE_CODE (op) == COMPLEX_CST)
04709 subop = TREE_REALPART (op);
04710 else
04711 subop = op;
04712
04713 if (TREE_CODE (subop) != INTEGER_CST
04714 && TREE_CODE (subop) != REAL_CST)
04715
04716
04717
04718 wins = 0;
04719
04720 if (i == 0)
04721 arg0 = op;
04722 else if (i == 1)
04723 arg1 = op;
04724 }
04725 }
04726
04727
04728
04729 if ((code == PLUS_EXPR || code == MULT_EXPR || code == MIN_EXPR
04730 || code == MAX_EXPR || code == BIT_IOR_EXPR || code == BIT_XOR_EXPR
04731 || code == BIT_AND_EXPR)
04732 && ((TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) != INTEGER_CST)
04733 || (TREE_CODE (arg0) == REAL_CST && TREE_CODE (arg1) != REAL_CST)))
04734 {
04735 tem = arg0; arg0 = arg1; arg1 = tem;
04736
04737 if (t == orig_t)
04738 t = copy_node (t);
04739 TREE_OPERAND (t, 0) = arg0;
04740 TREE_OPERAND (t, 1) = arg1;
04741 }
04742
04743
04744
04745
04746
04747
04748
04749
04750
04751
04752
04753
04754
04755
04756
04757
04758
04759
04760
04761 if ((code == BIT_AND_EXPR || code == BIT_IOR_EXPR
04762 || code == EQ_EXPR || code == NE_EXPR)
04763 && ((truth_value_p (TREE_CODE (arg0))
04764 && (truth_value_p (TREE_CODE (arg1))
04765 || (TREE_CODE (arg1) == BIT_AND_EXPR
04766 && integer_onep (TREE_OPERAND (arg1, 1)))))
04767 || (truth_value_p (TREE_CODE (arg1))
04768 && (truth_value_p (TREE_CODE (arg0))
04769 || (TREE_CODE (arg0) == BIT_AND_EXPR
04770 && integer_onep (TREE_OPERAND (arg0, 1)))))))
04771 {
04772 t = fold (build (code == BIT_AND_EXPR ? TRUTH_AND_EXPR
04773 : code == BIT_IOR_EXPR ? TRUTH_OR_EXPR
04774 : TRUTH_XOR_EXPR,
04775 type, arg0, arg1));
04776
04777 if (code == EQ_EXPR)
04778 t = invert_truthvalue (t);
04779
04780 return t;
04781 }
04782
04783 if (TREE_CODE_CLASS (code) == '1')
04784 {
04785 if (TREE_CODE (arg0) == COMPOUND_EXPR)
04786 return build (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
04787 fold (build1 (code, type, TREE_OPERAND (arg0, 1))));
04788 else if (TREE_CODE (arg0) == COND_EXPR)
04789 {
04790 tree arg01 = TREE_OPERAND (arg0, 1);
04791 tree arg02 = TREE_OPERAND (arg0, 2);
04792 if (! VOID_TYPE_P (TREE_TYPE (arg01)))
04793 arg01 = fold (build1 (code, type, arg01));
04794 if (! VOID_TYPE_P (TREE_TYPE (arg02)))
04795 arg02 = fold (build1 (code, type, arg02));
04796 t = fold (build (COND_EXPR, type, TREE_OPERAND (arg0, 0),
04797 arg01, arg02));
04798
04799
04800
04801
04802
04803
04804
04805
04806
04807
04808 if ((code == NOP_EXPR || code == CONVERT_EXPR
04809 || code == NON_LVALUE_EXPR)
04810 && TREE_CODE (t) == COND_EXPR
04811 && TREE_CODE (TREE_OPERAND (t, 1)) == code
04812 && TREE_CODE (TREE_OPERAND (t, 2)) == code
04813 && ! VOID_TYPE_P (TREE_OPERAND (t, 1))
04814 && ! VOID_TYPE_P (TREE_OPERAND (t, 2))
04815 && (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 1), 0))
04816 == TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 2), 0)))
04817 && ! (INTEGRAL_TYPE_P (TREE_TYPE (t))
04818 && (INTEGRAL_TYPE_P
04819 (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 1), 0))))
04820 && TYPE_PRECISION (TREE_TYPE (t)) <= BITS_PER_WORD))
04821 t = build1 (code, type,
04822 build (COND_EXPR,
04823 TREE_TYPE (TREE_OPERAND
04824 (TREE_OPERAND (t, 1), 0)),
04825 TREE_OPERAND (t, 0),
04826 TREE_OPERAND (TREE_OPERAND (t, 1), 0),
04827 TREE_OPERAND (TREE_OPERAND (t, 2), 0)));
04828 return t;
04829 }
04830 else if (TREE_CODE_CLASS (TREE_CODE (arg0)) == '<')
04831 return fold (build (COND_EXPR, type, arg0,
04832 fold (build1 (code, type, integer_one_node)),
04833 fold (build1 (code, type, integer_zero_node))));
04834 }
04835 else if (TREE_CODE_CLASS (code) == '2'
04836 || TREE_CODE_CLASS (code) == '<')
04837 {
04838 if (TREE_CODE (arg1) == COMPOUND_EXPR
04839 && ! TREE_SIDE_EFFECTS (TREE_OPERAND (arg1, 0))
04840 && ! TREE_SIDE_EFFECTS (arg0))
04841 return build (COMPOUND_EXPR, type, TREE_OPERAND (arg1, 0),
04842 fold (build (code, type,
04843 arg0, TREE_OPERAND (arg1, 1))));
04844 else if ((TREE_CODE (arg1) == COND_EXPR
04845 || (TREE_CODE_CLASS (TREE_CODE (arg1)) == '<'
04846 && TREE_CODE_CLASS (code) != '<'))
04847 && (TREE_CODE (arg0) != COND_EXPR
04848 || count_cond (arg0, 25) + count_cond (arg1, 25) <= 25)
04849 && (! TREE_SIDE_EFFECTS (arg0)
04850 || ((*lang_hooks.decls.global_bindings_p) () == 0
04851 && ! contains_placeholder_p (arg0))))
04852 return
04853 fold_binary_op_with_conditional_arg (code, type, arg1, arg0,
04854 0);
04855 else if (TREE_CODE (arg0) == COMPOUND_EXPR)
04856 return build (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
04857 fold (build (code, type, TREE_OPERAND (arg0, 1), arg1)));
04858 else if ((TREE_CODE (arg0) == COND_EXPR
04859 || (TREE_CODE_CLASS (TREE_CODE (arg0)) == '<'
04860 && TREE_CODE_CLASS (code) != '<'))
04861 && (TREE_CODE (arg1) != COND_EXPR
04862 || count_cond (arg0, 25) + count_cond (arg1, 25) <= 25)
04863 && (! TREE_SIDE_EFFECTS (arg1)
04864 || ((*lang_hooks.decls.global_bindings_p) () == 0
04865 && ! contains_placeholder_p (arg1))))
04866 return
04867 fold_binary_op_with_conditional_arg (code, type, arg0, arg1,
04868 1);
04869 }
04870 else if (TREE_CODE_CLASS (code) == '<'
04871 && TREE_CODE (arg0) == COMPOUND_EXPR)
04872 return build (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
04873 fold (build (code, type, TREE_OPERAND (arg0, 1), arg1)));
04874 else if (TREE_CODE_CLASS (code) == '<'
04875 && TREE_CODE (arg1) == COMPOUND_EXPR)
04876 return build (COMPOUND_EXPR, type, TREE_OPERAND (arg1, 0),
04877 fold (build (code, type, arg0, TREE_OPERAND (arg1, 1))));
04878
04879 switch (code)
04880 {
04881 case INTEGER_CST:
04882 case REAL_CST:
04883 case VECTOR_CST:
04884 case STRING_CST:
04885 case COMPLEX_CST:
04886 case CONSTRUCTOR:
04887 return t;
04888
04889 case CONST_DECL:
04890 return fold (DECL_INITIAL (t));
04891
04892 case NOP_EXPR:
04893 case FLOAT_EXPR:
04894 case CONVERT_EXPR:
04895 case FIX_TRUNC_EXPR:
04896
04897
04898 if (TREE_TYPE (TREE_OPERAND (t, 0)) == TREE_TYPE (t))
04899 return TREE_OPERAND (t, 0);
04900
04901
04902 if (TREE_CODE (TREE_OPERAND (t, 0)) == NOP_EXPR
04903 || TREE_CODE (TREE_OPERAND (t, 0)) == CONVERT_EXPR)
04904 {
04905 tree inside_type = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 0), 0));
04906 tree inter_type = TREE_TYPE (TREE_OPERAND (t, 0));
04907 tree final_type = TREE_TYPE (t);
04908 int inside_int = INTEGRAL_TYPE_P (inside_type);
04909 int inside_ptr = POINTER_TYPE_P (inside_type);
04910 int inside_float = FLOAT_TYPE_P (inside_type);
04911 unsigned int inside_prec = TYPE_PRECISION (inside_type);
04912 int inside_unsignedp = TREE_UNSIGNED (inside_type);
04913 int inter_int = INTEGRAL_TYPE_P (inter_type);
04914 int inter_ptr = POINTER_TYPE_P (inter_type);
04915 int inter_float = FLOAT_TYPE_P (inter_type);
04916 unsigned int inter_prec = TYPE_PRECISION (inter_type);
04917 int inter_unsignedp = TREE_UNSIGNED (inter_type);
04918 int final_int = INTEGRAL_TYPE_P (final_type);
04919 int final_ptr = POINTER_TYPE_P (final_type);
04920 int final_float = FLOAT_TYPE_P (final_type);
04921 unsigned int final_prec = TYPE_PRECISION (final_type);
04922 int final_unsignedp = TREE_UNSIGNED (final_type);
04923
04924
04925
04926
04927
04928 if (TYPE_MAIN_VARIANT (inside_type) == TYPE_MAIN_VARIANT (final_type)
04929 && ((inter_int && final_int) || (inter_float && final_float))
04930 && inter_prec >= final_prec)
04931 return convert (final_type, TREE_OPERAND (TREE_OPERAND (t, 0), 0));
04932
04933
04934
04935
04936
04937
04938
04939 if ((((inter_int || inter_ptr) && (inside_int || inside_ptr))
04940 || (inter_float && inside_float))
04941 && inter_prec >= inside_prec
04942 && (inter_float || inter_unsignedp == inside_unsignedp)
04943 && ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (final_type))
04944 && TYPE_MODE (final_type) == TYPE_MODE (inter_type))
04945 && ! final_ptr)
04946 return convert (final_type, TREE_OPERAND (TREE_OPERAND (t, 0), 0));
04947
04948
04949
04950 if (inside_int && inter_int && final_int
04951 && inside_prec < inter_prec && inter_prec < final_prec
04952 && inside_unsignedp && !inter_unsignedp)
04953 return convert (final_type, TREE_OPERAND (TREE_OPERAND (t, 0), 0));
04954
04955
04956
04957
04958
04959
04960
04961
04962
04963
04964
04965 if (! inside_float && ! inter_float && ! final_float
04966 && (inter_prec > inside_prec || inter_prec > final_prec)
04967 && ! (inside_int && inter_int
04968 && inter_unsignedp != inside_unsignedp
04969 && inter_prec < final_prec)
04970 && ((inter_unsignedp && inter_prec > inside_prec)
04971 == (final_unsignedp && final_prec > inter_prec))
04972 && ! (inside_ptr && inter_prec != final_prec)
04973 && ! (final_ptr && inside_prec != inter_prec)
04974 && ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (final_type))
04975 && TYPE_MODE (final_type) == TYPE_MODE (inter_type))
04976 && ! final_ptr)
04977 return convert (final_type, TREE_OPERAND (TREE_OPERAND (t, 0), 0));
04978 }
04979
04980 if (TREE_CODE (TREE_OPERAND (t, 0)) == MODIFY_EXPR
04981 && TREE_CONSTANT (TREE_OPERAND (TREE_OPERAND (t, 0), 1))
04982
04983 && !(TREE_CODE (TREE_OPERAND (TREE_OPERAND (t, 0), 0)) == COMPONENT_REF
04984 && DECL_BIT_FIELD (TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (t, 0), 0), 1))))
04985 {
04986
04987
04988 tree prev = TREE_OPERAND (t, 0);
04989 if (t == orig_t)
04990 t = copy_node (t);
04991 TREE_OPERAND (t, 0) = TREE_OPERAND (prev, 1);
04992
04993 t = build (COMPOUND_EXPR, TREE_TYPE (t), prev, fold (t));
04994 TREE_USED (t) = 1;
04995 return t;
04996 }
04997
04998
04999
05000
05001 if (INTEGRAL_TYPE_P (TREE_TYPE (t))
05002 && TREE_CODE (TREE_TYPE (t)) != BOOLEAN_TYPE
05003 && TREE_CODE (TREE_OPERAND (t, 0)) == BIT_AND_EXPR
05004 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t, 0), 1)) == INTEGER_CST)
05005 {
05006 tree and = TREE_OPERAND (t, 0);
05007 tree and0 = TREE_OPERAND (and, 0), and1 = TREE_OPERAND (and, 1);
05008 int change = 0;
05009
05010 if (TREE_UNSIGNED (TREE_TYPE (and))
05011 || (TYPE_PRECISION (TREE_TYPE (t))
05012 <= TYPE_PRECISION (TREE_TYPE (and))))
05013 change = 1;
05014 else if (TYPE_PRECISION (TREE_TYPE (and1))
05015 <= HOST_BITS_PER_WIDE_INT
05016 && host_integerp (and1, 1))
05017 {
05018 unsigned HOST_WIDE_INT cst;
05019
05020 cst = tree_low_cst (and1, 1);
05021 cst &= (HOST_WIDE_INT) -1
05022 << (TYPE_PRECISION (TREE_TYPE (and1)) - 1);
05023 change = (cst == 0);
05024 #ifdef LOAD_EXTEND_OP
05025 if (change
05026 && (LOAD_EXTEND_OP (TYPE_MODE (TREE_TYPE (and0)))
05027 == ZERO_EXTEND))
05028 {
05029 tree uns = (*lang_hooks.types.unsigned_type) (TREE_TYPE (and0));
05030 and0 = convert (uns, and0);
05031 and1 = convert (uns, and1);
05032 }
05033 #endif
05034 }
05035 if (change)
05036 return fold (build (BIT_AND_EXPR, TREE_TYPE (t),
05037 convert (TREE_TYPE (t), and0),
05038 convert (TREE_TYPE (t), and1)));
05039 }
05040
05041 if (!wins)
05042 {
05043 if (TREE_CONSTANT (t) != TREE_CONSTANT (arg0))
05044 {
05045 if (t == orig_t)
05046 t = copy_node (t);
05047 TREE_CONSTANT (t) = TREE_CONSTANT (arg0);
05048 }
05049 return t;
05050 }
05051 return fold_convert (t, arg0);
05052
05053 case VIEW_CONVERT_EXPR:
05054 if (TREE_CODE (TREE_OPERAND (t, 0)) == VIEW_CONVERT_EXPR)
05055 return build1 (VIEW_CONVERT_EXPR, type,
05056 TREE_OPERAND (TREE_OPERAND (t, 0), 0));
05057 return t;
05058
05059 case COMPONENT_REF:
05060 if (TREE_CODE (arg0) == CONSTRUCTOR)
05061 {
05062 tree m = purpose_member (arg1, CONSTRUCTOR_ELTS (arg0));
05063 if (m)
05064 t = TREE_VALUE (m);
05065 }
05066 return t;
05067
05068 case RANGE_EXPR:
05069 if (TREE_CONSTANT (t) != wins)
05070 {
05071 if (t == orig_t)
05072 t = copy_node (t);
05073 TREE_CONSTANT (t) = wins;
05074 }
05075 return t;
05076
05077 case NEGATE_EXPR:
05078 if (wins)
05079 {
05080 if (TREE_CODE (arg0) == INTEGER_CST)
05081 {
05082 unsigned HOST_WIDE_INT low;
05083 HOST_WIDE_INT high;
05084 int overflow = neg_double (TREE_INT_CST_LOW (arg0),
05085 TREE_INT_CST_HIGH (arg0),
05086 &low, &high);
05087 t = build_int_2 (low, high);
05088 TREE_TYPE (t) = type;
05089 TREE_OVERFLOW (t)
05090 = (TREE_OVERFLOW (arg0)
05091 | force_fit_type (t, overflow && !TREE_UNSIGNED (type)));
05092 TREE_CONSTANT_OVERFLOW (t)
05093 = TREE_OVERFLOW (t) | TREE_CONSTANT_OVERFLOW (arg0);
05094 }
05095 else if (TREE_CODE (arg0) == REAL_CST)
05096 t = build_real (type, REAL_VALUE_NEGATE (TREE_REAL_CST (arg0)));
05097 }
05098 else if (TREE_CODE (arg0) == NEGATE_EXPR)
05099 #ifdef KEY // bug 2685
05100 return convert (type, TREE_OPERAND (arg0,0));
05101 #else
05102 return TREE_OPERAND (arg0, 0);
05103 #endif // KEY
05104
05105
05106 else if (TREE_CODE (arg0) == MINUS_EXPR
05107 && (! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations))
05108 return build (MINUS_EXPR, type, TREE_OPERAND (arg0, 1),
05109 TREE_OPERAND (arg0, 0));
05110
05111 return t;
05112
05113 case ABS_EXPR:
05114 if (wins)
05115 {
05116 if (TREE_CODE (arg0) == INTEGER_CST)
05117 {
05118
05119
05120 if (TREE_UNSIGNED (type))
05121 return arg0;
05122
05123 else if (INT_CST_LT (integer_minus_one_node, arg0))
05124 return arg0;
05125
05126
05127 else
05128 {
05129 unsigned HOST_WIDE_INT low;
05130 HOST_WIDE_INT high;
05131 int overflow = neg_double (TREE_INT_CST_LOW (arg0),
05132 TREE_INT_CST_HIGH (arg0),
05133 &low, &high);
05134 t = build_int_2 (low, high);
05135 TREE_TYPE (t) = type;
05136 TREE_OVERFLOW (t)
05137 = (TREE_OVERFLOW (arg0)
05138 | force_fit_type (t, overflow));
05139 TREE_CONSTANT_OVERFLOW (t)
05140 = TREE_OVERFLOW (t) | TREE_CONSTANT_OVERFLOW (arg0);
05141 }
05142 }
05143 else if (TREE_CODE (arg0) == REAL_CST)
05144 {
05145 if (REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg0)))
05146 t = build_real (type,
05147 REAL_VALUE_NEGATE (TREE_REAL_CST (arg0)));
05148 }
05149 }
05150 else if (TREE_CODE (arg0) == ABS_EXPR || TREE_CODE (arg0) == NEGATE_EXPR)
05151 return build1 (ABS_EXPR, type, TREE_OPERAND (arg0, 0));
05152 return t;
05153
05154 case CONJ_EXPR:
05155 if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
05156 return convert (type, arg0);
05157 else if (TREE_CODE (arg0) == COMPLEX_EXPR)
05158 return build (COMPLEX_EXPR, type,
05159 TREE_OPERAND (arg0, 0),
05160 negate_expr (TREE_OPERAND (arg0, 1)));
05161 else if (TREE_CODE (arg0) == COMPLEX_CST)
05162 return build_complex (type, TREE_REALPART (arg0),
05163 negate_expr (TREE_IMAGPART (arg0)));
05164 else if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
05165 return fold (build (TREE_CODE (arg0), type,
05166 fold (build1 (CONJ_EXPR, type,
05167 TREE_OPERAND (arg0, 0))),
05168 fold (build1 (CONJ_EXPR,
05169 type, TREE_OPERAND (arg0, 1)))));
05170 else if (TREE_CODE (arg0) == CONJ_EXPR)
05171 return TREE_OPERAND (arg0, 0);
05172 return t;
05173
05174 case BIT_NOT_EXPR:
05175 if (wins)
05176 {
05177 t = build_int_2 (~ TREE_INT_CST_LOW (arg0),
05178 ~ TREE_INT_CST_HIGH (arg0));
05179 TREE_TYPE (t) = type;
05180 force_fit_type (t, 0);
05181 TREE_OVERFLOW (t) = TREE_OVERFLOW (arg0);
05182 TREE_CONSTANT_OVERFLOW (t) = TREE_CONSTANT_OVERFLOW (arg0);
05183 }
05184 else if (TREE_CODE (arg0) == BIT_NOT_EXPR)
05185 #ifdef KEY // bug 2772
05186 return convert (type, TREE_OPERAND (arg0, 0));
05187 #else
05188 return TREE_OPERAND (arg0, 0);
05189 #endif
05190 return t;
05191
05192 case PLUS_EXPR:
05193
05194 if (TREE_CODE (arg1) == NEGATE_EXPR)
05195 return fold (build (MINUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0)));
05196
05197 if (TREE_CODE (arg0) == NEGATE_EXPR)
05198 return fold (build (MINUS_EXPR, type, arg1, TREE_OPERAND (arg0, 0)));
05199 else if (! FLOAT_TYPE_P (type))
05200 {
05201 if (integer_zerop (arg1))
05202 return non_lvalue (convert (type, arg0));
05203
05204
05205
05206
05207
05208 if (TREE_CODE (arg0) == BIT_AND_EXPR
05209 && TREE_CODE (arg1) == BIT_AND_EXPR
05210 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
05211 && TREE_CODE (TREE_OPERAND (arg1, 1)) == INTEGER_CST
05212 && integer_zerop (const_binop (BIT_AND_EXPR,
05213 TREE_OPERAND (arg0, 1),
05214 TREE_OPERAND (arg1, 1), 0)))
05215 {
05216 code = BIT_IOR_EXPR;
05217 goto bit_ior;
05218 }
05219
05220
05221
05222
05223 if ((TREE_CODE (arg0) == PLUS_EXPR
05224 && TREE_CODE (arg1) == MULT_EXPR)
05225 || (TREE_CODE (arg1) == PLUS_EXPR
05226 && TREE_CODE (arg0) == MULT_EXPR))
05227 {
05228 tree parg0, parg1, parg, marg;
05229
05230 if (TREE_CODE (arg0) == PLUS_EXPR)
05231 parg = arg0, marg = arg1;
05232 else
05233 parg = arg1, marg = arg0;
05234 parg0 = TREE_OPERAND (parg, 0);
05235 parg1 = TREE_OPERAND (parg, 1);
05236 STRIP_NOPS (parg0);
05237 STRIP_NOPS (parg1);
05238
05239 if (TREE_CODE (parg0) == MULT_EXPR
05240 && TREE_CODE (parg1) != MULT_EXPR)
05241 return fold (build (PLUS_EXPR, type,
05242 fold (build (PLUS_EXPR, type, parg0, marg)),
05243 parg1));
05244 if (TREE_CODE (parg0) != MULT_EXPR
05245 && TREE_CODE (parg1) == MULT_EXPR)
05246 return fold (build (PLUS_EXPR, type,
05247 fold (build (PLUS_EXPR, type, parg1, marg)),
05248 parg0));
05249 }
05250
05251 if (TREE_CODE (arg0) == MULT_EXPR && TREE_CODE (arg1) == MULT_EXPR)
05252 {
05253 tree arg00, arg01, arg10, arg11;
05254 tree alt0 = NULL_TREE, alt1 = NULL_TREE, same;
05255
05256
05257
05258
05259
05260
05261 arg00 = TREE_OPERAND (arg0, 0);
05262 arg01 = TREE_OPERAND (arg0, 1);
05263 arg10 = TREE_OPERAND (arg1, 0);
05264 arg11 = TREE_OPERAND (arg1, 1);
05265 same = NULL_TREE;
05266
05267 if (operand_equal_p (arg01, arg11, 0))
05268 same = arg01, alt0 = arg00, alt1 = arg10;
05269 else if (operand_equal_p (arg00, arg10, 0))
05270 same = arg00, alt0 = arg01, alt1 = arg11;
05271 else if (operand_equal_p (arg00, arg11, 0))
05272 same = arg00, alt0 = arg01, alt1 = arg10;
05273 else if (operand_equal_p (arg01, arg10, 0))
05274 same = arg01, alt0 = arg00, alt1 = arg11;
05275
05276
05277
05278
05279 else if (TREE_CODE (arg01) == INTEGER_CST
05280 && TREE_CODE (arg11) == INTEGER_CST
05281 && TREE_INT_CST_HIGH (arg01) == 0
05282 && TREE_INT_CST_HIGH (arg11) == 0)
05283 {
05284 HOST_WIDE_INT int01, int11, tmp;
05285 int01 = TREE_INT_CST_LOW (arg01);
05286 int11 = TREE_INT_CST_LOW (arg11);
05287
05288
05289 if ((int01 >= 0 ? int01 : -int01)
05290 < (int11 >= 0 ? int11 : -int11))
05291 {
05292 tmp = int01, int01 = int11, int11 = tmp;
05293 alt0 = arg00, arg00 = arg10, arg10 = alt0;
05294 alt0 = arg01, arg01 = arg11, arg11 = alt0;
05295 }
05296
05297 if (exact_log2 (int11) > 0 && int01 % int11 == 0)
05298 {
05299 alt0 = fold (build (MULT_EXPR, type, arg00,
05300 build_int_2 (int01 / int11, 0)));
05301 alt1 = arg10;
05302 same = arg11;
05303 }
05304 }
05305
05306 if (same)
05307 return fold (build (MULT_EXPR, type,
05308 fold (build (PLUS_EXPR, type, alt0, alt1)),
05309 same));
05310 }
05311 }
05312
05313
05314 else if (fold_real_zero_addition_p (TREE_TYPE (arg0), arg1, 0))
05315 return non_lvalue (convert (type, arg0));
05316
05317
05318 else if (fold_real_zero_addition_p (TREE_TYPE (arg1), arg0, 0))
05319 return non_lvalue (convert (type, arg1));
05320
05321 bit_rotate:
05322
05323
05324
05325
05326 {
05327 enum tree_code code0, code1;
05328 code0 = TREE_CODE (arg0);
05329 code1 = TREE_CODE (arg1);
05330 if (((code0 == RSHIFT_EXPR && code1 == LSHIFT_EXPR)
05331 || (code1 == RSHIFT_EXPR && code0 == LSHIFT_EXPR))
05332 && operand_equal_p (TREE_OPERAND (arg0, 0),
05333 TREE_OPERAND (arg1, 0), 0)
05334 && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg0, 0))))
05335 {
05336 tree tree01, tree11;
05337 enum tree_code code01, code11;
05338
05339 tree01 = TREE_OPERAND (arg0, 1);
05340 tree11 = TREE_OPERAND (arg1, 1);
05341 STRIP_NOPS (tree01);
05342 STRIP_NOPS (tree11);
05343 code01 = TREE_CODE (tree01);
05344 code11 = TREE_CODE (tree11);
05345 if (code01 == INTEGER_CST
05346 && code11 == INTEGER_CST
05347 && TREE_INT_CST_HIGH (tree01) == 0
05348 && TREE_INT_CST_HIGH (tree11) == 0
05349 && ((TREE_INT_CST_LOW (tree01) + TREE_INT_CST_LOW (tree11))
05350 == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)))))
05351 return build (LROTATE_EXPR, type, TREE_OPERAND (arg0, 0),
05352 code0 == LSHIFT_EXPR ? tree01 : tree11);
05353 else if (code11 == MINUS_EXPR)
05354 {
05355 tree tree110, tree111;
05356 tree110 = TREE_OPERAND (tree11, 0);
05357 tree111 = TREE_OPERAND (tree11, 1);
05358 STRIP_NOPS (tree110);
05359 STRIP_NOPS (tree111);
05360 if (TREE_CODE (tree110) == INTEGER_CST
05361 && 0 == compare_tree_int (tree110,
05362 TYPE_PRECISION
05363 (TREE_TYPE (TREE_OPERAND
05364 (arg0, 0))))
05365 && operand_equal_p (tree01, tree111, 0))
05366 return build ((code0 == LSHIFT_EXPR
05367 ? LROTATE_EXPR
05368 : RROTATE_EXPR),
05369 type, TREE_OPERAND (arg0, 0), tree01);
05370 }
05371 else if (code01 == MINUS_EXPR)
05372 {
05373 tree tree010, tree011;
05374 tree010 = TREE_OPERAND (tree01, 0);
05375 tree011 = TREE_OPERAND (tree01, 1);
05376 STRIP_NOPS (tree010);
05377 STRIP_NOPS (tree011);
05378 if (TREE_CODE (tree010) == INTEGER_CST
05379 && 0 == compare_tree_int (tree010,
05380 TYPE_PRECISION
05381 (TREE_TYPE (TREE_OPERAND
05382 (arg0, 0))))
05383 && operand_equal_p (tree11, tree011, 0))
05384 return build ((code0 != LSHIFT_EXPR
05385 ? LROTATE_EXPR
05386 : RROTATE_EXPR),
05387 type, TREE_OPERAND (arg0, 0), tree11);
05388 }
05389 }
05390 }
05391
05392 associate:
05393
05394
05395
05396
05397
05398
05399 if (! wins
05400 && (! FLOAT_TYPE_P (type)
05401 || (flag_unsafe_math_optimizations && code == MULT_EXPR)))
05402 {
05403 tree var0, con0, lit0, minus_lit0;
05404 tree var1, con1, lit1, minus_lit1;
05405
05406
05407
05408
05409
05410
05411 var0 = split_tree (arg0, code, &con0, &lit0, &minus_lit0, 0);
05412 var1 = split_tree (arg1, code, &con1, &lit1, &minus_lit1,
05413 code == MINUS_EXPR);
05414
05415
05416
05417 if (2 < ((var0 != 0) + (var1 != 0)
05418 + (con0 != 0) + (con1 != 0)
05419 + (lit0 != 0) + (lit1 != 0)
05420 + (minus_lit0 != 0) + (minus_lit1 != 0)))
05421 {
05422
05423 if (code == MINUS_EXPR)
05424 code = PLUS_EXPR;
05425
05426 var0 = associate_trees (var0, var1, code, type);
05427 con0 = associate_trees (con0, con1, code, type);
05428 lit0 = associate_trees (lit0, lit1, code, type);
05429 minus_lit0 = associate_trees (minus_lit0, minus_lit1, code, type);
05430
05431
05432
05433
05434
05435
05436 if (minus_lit0 && lit0)
05437 {
05438 if (tree_int_cst_lt (lit0, minus_lit0))
05439 {
05440 minus_lit0 = associate_trees (minus_lit0, lit0,
05441 MINUS_EXPR, type);
05442 lit0 = 0;
05443 }
05444 else
05445 {
05446 lit0 = associate_trees (lit0, minus_lit0,
05447 MINUS_EXPR, type);
05448 minus_lit0 = 0;
05449 }
05450 }
05451 if (minus_lit0)
05452 {
05453 if (con0 == 0)
05454 return convert (type, associate_trees (var0, minus_lit0,
05455 MINUS_EXPR, type));
05456 else
05457 {
05458 con0 = associate_trees (con0, minus_lit0,
05459 MINUS_EXPR, type);
05460 return convert (type, associate_trees (var0, con0,
05461 PLUS_EXPR, type));
05462 }
05463 }
05464
05465 con0 = associate_trees (con0, lit0, code, type);
05466 return convert (type, associate_trees (var0, con0, code, type));
05467 }
05468 }
05469
05470 binary:
05471 if (wins)
05472 t1 = const_binop (code, arg0, arg1, 0);
05473 if (t1 != NULL_TREE)
05474 {
05475
05476
05477 if (TREE_TYPE (t1) != TREE_TYPE (t))
05478 t1 = convert (TREE_TYPE (t), t1);
05479
05480 return t1;
05481 }
05482 return t;
05483
05484 case MINUS_EXPR:
05485
05486 if (TREE_CODE (arg1) == NEGATE_EXPR)
05487 return fold (build (PLUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0)));
05488
05489 if (TREE_CODE (arg0) == NEGATE_EXPR && TREE_CODE (arg1) == REAL_CST)
05490 return
05491 fold (build (MINUS_EXPR, type,
05492 build_real (TREE_TYPE (arg1),
05493 REAL_VALUE_NEGATE (TREE_REAL_CST (arg1))),
05494 TREE_OPERAND (arg0, 0)));
05495
05496 if (! FLOAT_TYPE_P (type))
05497 {
05498 if (! wins && integer_zerop (arg0))
05499 return negate_expr (convert (type, arg1));
05500 if (integer_zerop (arg1))
05501 return non_lvalue (convert (type, arg0));
05502
05503
05504
05505
05506
05507 if (TREE_CODE (arg0) == MULT_EXPR && TREE_CODE (arg1) == MULT_EXPR
05508 && operand_equal_p (TREE_OPERAND (arg0, 1),
05509 TREE_OPERAND (arg1, 1), 0))
05510 return fold (build (MULT_EXPR, type,
05511 fold (build (MINUS_EXPR, type,
05512 TREE_OPERAND (arg0, 0),
05513 TREE_OPERAND (arg1, 0))),
05514 TREE_OPERAND (arg0, 1)));
05515 }
05516
05517
05518 else if (fold_real_zero_addition_p (TREE_TYPE (arg0), arg1, 1))
05519 return non_lvalue (convert (type, arg0));
05520
05521
05522
05523
05524 else if (!wins && fold_real_zero_addition_p (TREE_TYPE (arg1), arg0, 0))
05525 return negate_expr (convert (type, arg1));
05526
05527
05528
05529
05530
05531
05532
05533 if ((! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
05534 && operand_equal_p (arg0, arg1, 0))
05535 return convert (type, integer_zero_node);
05536
05537 goto associate;
05538
05539 case MULT_EXPR:
05540
05541 if (TREE_CODE (arg0) == NEGATE_EXPR && TREE_CODE (arg1) == NEGATE_EXPR)
05542 return fold (build (MULT_EXPR, type, TREE_OPERAND (arg0, 0),
05543 TREE_OPERAND (arg1, 0)));
05544
05545 if (! FLOAT_TYPE_P (type))
05546 {
05547 if (integer_zerop (arg1))
05548 return omit_one_operand (type, arg1, arg0);
05549 if (integer_onep (arg1))
05550 return non_lvalue (convert (type, arg0));
05551
05552
05553 if (TREE_CODE (arg1) == LSHIFT_EXPR
05554 && integer_onep (TREE_OPERAND (arg1, 0)))
05555 return fold (build (LSHIFT_EXPR, type, arg0,
05556 TREE_OPERAND (arg1, 1)));
05557 if (TREE_CODE (arg0) == LSHIFT_EXPR
05558 && integer_onep (TREE_OPERAND (arg0, 0)))
05559 return fold (build (LSHIFT_EXPR, type, arg1,
05560 TREE_OPERAND (arg0, 1)));
05561
05562 if (TREE_CODE (arg1) == INTEGER_CST
05563 && 0 != (tem = extract_muldiv (TREE_OPERAND (t, 0), arg1,
05564 code, NULL_TREE)))
05565 return convert (type, tem);
05566
05567 }
05568 else
05569 {
05570
05571
05572
05573
05574 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0)))
05575 && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg0)))
05576 && real_zerop (arg1))
05577 return omit_one_operand (type, arg1, arg0);
05578
05579 if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
05580 && real_onep (arg1))
05581 return non_lvalue (convert (type, arg0));
05582
05583
05584 if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
05585 && real_minus_onep (arg1))
05586 return fold (build1 (NEGATE_EXPR, type, arg0));
05587
05588
05589 if (! wins && real_twop (arg1)
05590 && (*lang_hooks.decls.global_bindings_p) () == 0
05591 && ! contains_placeholder_p (arg0))
05592 {
05593 tree arg = save_expr (arg0);
05594 return build (PLUS_EXPR, type, arg, arg);
05595 }
05596 }
05597 goto associate;
05598
05599 case BIT_IOR_EXPR:
05600 bit_ior:
05601 if (integer_all_onesp (arg1))
05602 return omit_one_operand (type, arg1, arg0);
05603 if (integer_zerop (arg1))
05604 return non_lvalue (convert (type, arg0));
05605 t1 = distribute_bit_expr (code, type, arg0, arg1);
05606 if (t1 != NULL_TREE)
05607 return t1;
05608
05609
05610
05611
05612
05613
05614
05615 if (TREE_CODE (arg0) == BIT_NOT_EXPR
05616 && TREE_CODE (arg1) == BIT_NOT_EXPR)
05617 {
05618 return fold (build1 (BIT_NOT_EXPR, type,
05619 build (BIT_AND_EXPR, type,
05620 TREE_OPERAND (arg0, 0),
05621 TREE_OPERAND (arg1, 0))));
05622 }
05623
05624
05625
05626 goto bit_rotate;
05627
05628 case BIT_XOR_EXPR:
05629 if (integer_zerop (arg1))
05630 return non_lvalue (convert (type, arg0));
05631 if (integer_all_onesp (arg1))
05632 return fold (build1 (BIT_NOT_EXPR, type, arg0));
05633
05634
05635
05636
05637
05638 if (TREE_CODE (arg0) == BIT_AND_EXPR
05639 && TREE_CODE (arg1) == BIT_AND_EXPR
05640 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
05641 && TREE_CODE (TREE_OPERAND (arg1, 1)) == INTEGER_CST
05642 && integer_zerop (const_binop (BIT_AND_EXPR,
05643 TREE_OPERAND (arg0, 1),
05644 TREE_OPERAND (arg1, 1), 0)))
05645 {
05646 code = BIT_IOR_EXPR;
05647 goto bit_ior;
05648 }
05649
05650
05651
05652 goto bit_rotate;
05653
05654 case BIT_AND_EXPR:
05655 bit_and:
05656 if (integer_all_onesp (arg1))
05657 return non_lvalue (convert (type, arg0));
05658 if (integer_zerop (arg1))
05659 return omit_one_operand (type, arg1, arg0);
05660 t1 = distribute_bit_expr (code, type, arg0, arg1);
05661 if (t1 != NULL_TREE)
05662 return t1;
05663
05664 if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg0) == NOP_EXPR
05665 && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg0, 0))))
05666 {
05667 unsigned int prec
05668 = TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)));
05669
05670 if (prec < BITS_PER_WORD && prec < HOST_BITS_PER_WIDE_INT
05671 && (~TREE_INT_CST_LOW (arg1)
05672 & (((HOST_WIDE_INT) 1 << prec) - 1)) == 0)
05673 return build1 (NOP_EXPR, type, TREE_OPERAND (arg0, 0));
05674 }
05675
05676
05677
05678
05679
05680
05681
05682 if (TREE_CODE (arg0) == BIT_NOT_EXPR
05683 && TREE_CODE (arg1) == BIT_NOT_EXPR)
05684 {
05685 return fold (build1 (BIT_NOT_EXPR, type,
05686 build (BIT_IOR_EXPR, type,
05687 TREE_OPERAND (arg0, 0),
05688 TREE_OPERAND (arg1, 0))));
05689 }
05690
05691 goto associate;
05692
05693 case BIT_ANDTC_EXPR:
05694 if (integer_all_onesp (arg0))
05695 return non_lvalue (convert (type, arg1));
05696 if (integer_zerop (arg0))
05697 return omit_one_operand (type, arg0, arg1);
05698 if (TREE_CODE (arg1) == INTEGER_CST)
05699 {
05700 arg1 = fold (build1 (BIT_NOT_EXPR, type, arg1));
05701 code = BIT_AND_EXPR;
05702 goto bit_and;
05703 }
05704 goto binary;
05705
05706 case RDIV_EXPR:
05707
05708
05709 if (TREE_CODE (arg1) == REAL_CST
05710 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg1)))
05711 && real_zerop (arg1))
05712 return t;
05713
05714
05715 if (TREE_CODE (arg0) == NEGATE_EXPR && TREE_CODE (arg1) == NEGATE_EXPR)
05716 return fold (build (RDIV_EXPR, type, TREE_OPERAND (arg0, 0),
05717 TREE_OPERAND (arg1, 0)));
05718
05719
05720 if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
05721 && real_onep (arg1))
05722 return non_lvalue (convert (type, arg0));
05723
05724
05725
05726
05727
05728
05729 if (TREE_CODE (arg1) == REAL_CST)
05730 {
05731 if (flag_unsafe_math_optimizations
05732 && 0 != (tem = const_binop (code, build_real (type, dconst1),
05733 arg1, 0)))
05734 return fold (build (MULT_EXPR, type, arg0, tem));
05735
05736 else if (optimize)
05737 {
05738 REAL_VALUE_TYPE r;
05739 r = TREE_REAL_CST (arg1);
05740 if (exact_real_inverse (TYPE_MODE(TREE_TYPE(arg0)), &r))
05741 {
05742 tem = build_real (type, r);
05743 return fold (build (MULT_EXPR, type, arg0, tem));
05744 }
05745 }
05746 }
05747
05748 if (flag_unsafe_math_optimizations
05749 && TREE_CODE (arg0) == RDIV_EXPR)
05750 {
05751 return fold (build (RDIV_EXPR, type, TREE_OPERAND (arg0, 0),
05752 build (MULT_EXPR, type, TREE_OPERAND (arg0, 1),
05753 arg1)));
05754 }
05755
05756 if (flag_unsafe_math_optimizations
05757 && TREE_CODE (arg1) == RDIV_EXPR)
05758 {
05759 return fold (build (MULT_EXPR, type,
05760 build (RDIV_EXPR, type, arg0,
05761 TREE_OPERAND (arg1, 0)),
05762 TREE_OPERAND (arg1, 1)));
05763 }
05764 goto binary;
05765
05766 case TRUNC_DIV_EXPR:
05767 case ROUND_DIV_EXPR:
05768 case FLOOR_DIV_EXPR:
05769 case CEIL_DIV_EXPR:
05770 case EXACT_DIV_EXPR:
05771 if (integer_onep (arg1))
05772 return non_lvalue (convert (type, arg0));
05773 if (integer_zerop (arg1))
05774 return t;
05775
05776
05777
05778
05779
05780
05781
05782 if ((code == CEIL_DIV_EXPR || code == FLOOR_DIV_EXPR)
05783 && multiple_of_p (type, arg0, arg1))
05784 return fold (build (EXACT_DIV_EXPR, type, arg0, arg1));
05785
05786 if (TREE_CODE (arg1) == INTEGER_CST
05787 && 0 != (tem = extract_muldiv (TREE_OPERAND (t, 0), arg1,
05788 code, NULL_TREE)))
05789 return convert (type, tem);
05790
05791 goto binary;
05792
05793 case CEIL_MOD_EXPR:
05794 case FLOOR_MOD_EXPR:
05795 case ROUND_MOD_EXPR:
05796 case TRUNC_MOD_EXPR:
05797 if (integer_onep (arg1))
05798 return omit_one_operand (type, integer_zero_node, arg0);
05799 if (integer_zerop (arg1))
05800 return t;
05801
05802 if (TREE_CODE (arg1) == INTEGER_CST
05803 && 0 != (tem = extract_muldiv (TREE_OPERAND (t, 0), arg1,
05804 code, NULL_TREE)))
05805 return convert (type, tem);
05806
05807 goto binary;
05808
05809 case LSHIFT_EXPR:
05810 case RSHIFT_EXPR:
05811 case LROTATE_EXPR:
05812 case RROTATE_EXPR:
05813 if (integer_zerop (arg1))
05814 return non_lvalue (convert (type, arg0));
05815
05816
05817 if (TREE_CODE (arg1) == INTEGER_CST && tree_int_cst_sgn (arg1) < 0)
05818 return t;
05819
05820
05821 if (code == LROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST)
05822 {
05823 if (t == orig_t)
05824 t = copy_node (t);
05825 TREE_SET_CODE (t, RROTATE_EXPR);
05826 code = RROTATE_EXPR;
05827 TREE_OPERAND (t, 1) = arg1
05828 = const_binop
05829 (MINUS_EXPR,
05830 convert (TREE_TYPE (arg1),
05831 build_int_2 (GET_MODE_BITSIZE (TYPE_MODE (type)), 0)),
05832 arg1, 0);
05833 if (tree_int_cst_sgn (arg1) < 0)
05834 return t;
05835 }
05836
05837
05838
05839
05840 if (code == RROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST
05841 && (TREE_CODE (arg0) == BIT_AND_EXPR
05842 || TREE_CODE (arg0) == BIT_ANDTC_EXPR
05843 || TREE_CODE (arg0) == BIT_IOR_EXPR
05844 || TREE_CODE (arg0) == BIT_XOR_EXPR)
05845 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
05846 return fold (build (TREE_CODE (arg0), type,
05847 fold (build (code, type,
05848 TREE_OPERAND (arg0, 0), arg1)),
05849 fold (build (code, type,
05850 TREE_OPERAND (arg0, 1), arg1))));
05851
05852
05853
05854 if (code == RROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST
05855 && TREE_CODE (arg0) == RROTATE_EXPR
05856 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
05857 && TREE_INT_CST_HIGH (arg1) == 0
05858 && TREE_INT_CST_HIGH (TREE_OPERAND (arg0, 1)) == 0
05859 && ((TREE_INT_CST_LOW (arg1)
05860 + TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1)))
05861 == (unsigned int) GET_MODE_BITSIZE (TYPE_MODE (type))))
05862 return TREE_OPERAND (arg0, 0);
05863
05864 goto binary;
05865
05866 case MIN_EXPR:
05867 if (operand_equal_p (arg0, arg1, 0))
05868 return omit_one_operand (type, arg0, arg1);
05869 if (INTEGRAL_TYPE_P (type)
05870 && operand_equal_p (arg1, TYPE_MIN_VALUE (type), 1))
05871 return omit_one_operand (type, arg1, arg0);
05872 goto associate;
05873
05874 case MAX_EXPR:
05875 if (operand_equal_p (arg0, arg1, 0))
05876 return omit_one_operand (type, arg0, arg1);
05877 if (INTEGRAL_TYPE_P (type)
05878 && TYPE_MAX_VALUE (type)
05879 && operand_equal_p (arg1, TYPE_MAX_VALUE (type), 1))
05880 return omit_one_operand (type, arg1, arg0);
05881 goto associate;
05882
05883 case TRUTH_NOT_EXPR:
05884
05885
05886
05887
05888 tem = invert_truthvalue (arg0);
05889
05890 if (TREE_CODE (tem) == TRUTH_NOT_EXPR)
05891 return t;
05892 return convert (type, tem);
05893
05894 case TRUTH_ANDIF_EXPR:
05895
05896
05897
05898
05899 if (integer_zerop (arg0))
05900 return convert (type, arg0);
05901 case TRUTH_AND_EXPR:
05902
05903 if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0))
05904 return non_lvalue (convert (type, arg1));
05905 if (TREE_CODE (arg1) == INTEGER_CST && ! integer_zerop (arg1)
05906
05907 && (code != TRUTH_ANDIF_EXPR || ! TREE_SIDE_EFFECTS (arg0)))
05908 return non_lvalue (convert (type, arg0));
05909
05910
05911 if (integer_zerop (arg1))
05912 return omit_one_operand (type, arg1, arg0);
05913
05914
05915 if (integer_zerop (arg0))
05916 return omit_one_operand (type, arg0, arg1);
05917
05918 truth_andor:
05919
05920 if (!optimize)
05921 return t;
05922
05923
05924
05925
05926
05927
05928
05929 if (TREE_CODE (arg0) == TREE_CODE (arg1)
05930 && (TREE_CODE (arg0) == TRUTH_ANDIF_EXPR
05931 || TREE_CODE (arg0) == TRUTH_ORIF_EXPR
05932 || TREE_CODE (arg0) == TRUTH_AND_EXPR
05933 || TREE_CODE (arg0) == TRUTH_OR_EXPR)
05934 && ! TREE_SIDE_EFFECTS (TREE_OPERAND (arg0, 1)))
05935 {
05936 tree a00 = TREE_OPERAND (arg0, 0);
05937 tree a01 = TREE_OPERAND (arg0, 1);
05938 tree a10 = TREE_OPERAND (arg1, 0);
05939 tree a11 = TREE_OPERAND (arg1, 1);
05940 int commutative = ((TREE_CODE (arg0) == TRUTH_OR_EXPR
05941 || TREE_CODE (arg0) == TRUTH_AND_EXPR)
05942 && (code == TRUTH_AND_EXPR
05943 || code == TRUTH_OR_EXPR));
05944
05945 if (operand_equal_p (a00, a10, 0))
05946 return fold (build (TREE_CODE (arg0), type, a00,
05947 fold (build (code, type, a01, a11))));
05948 else if (commutative && operand_equal_p (a00, a11, 0))
05949 return fold (build (TREE_CODE (arg0), type, a00,
05950 fold (build (code, type, a01, a10))));
05951 else if (commutative && operand_equal_p (a01, a10, 0))
05952 return fold (build (TREE_CODE (arg0), type, a01,
05953 fold (build (code, type, a00, a11))));
05954
05955
05956
05957
05958 else if ((commutative || ! TREE_SIDE_EFFECTS (a10))
05959 && operand_equal_p (a01, a11, 0))
05960 return fold (build (TREE_CODE (arg0), type,
05961 fold (build (code, type, a00, a10)),
05962 a01));
05963 }
05964
05965
05966 if (0 != (tem = fold_range_test (t)))
05967 return tem;
05968
05969
05970
05971
05972 if (TREE_CODE (arg0) == code
05973 && 0 != (tem = fold_truthop (code, type,
05974 TREE_OPERAND (arg0, 1), arg1)))
05975 return fold (build (code, type, TREE_OPERAND (arg0, 0), tem));
05976
05977 if ((tem = fold_truthop (code, type, arg0, arg1)) != 0)
05978 return tem;
05979
05980 return t;
05981
05982 case TRUTH_ORIF_EXPR:
05983
05984
05985
05986
05987 if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0))
05988 return convert (type, arg0);
05989 case TRUTH_OR_EXPR:
05990
05991 if (TREE_CODE (arg0) == INTEGER_CST && integer_zerop (arg0))
05992 return non_lvalue (convert (type, arg1));
05993 if (TREE_CODE (arg1) == INTEGER_CST && integer_zerop (arg1)
05994
05995 && (code != TRUTH_ORIF_EXPR || ! TREE_SIDE_EFFECTS (arg0)))
05996 return non_lvalue (convert (type, arg0));
05997
05998
05999 if (TREE_CODE (arg1) == INTEGER_CST && ! integer_zerop (arg1))
06000 return omit_one_operand (type, arg1, arg0);
06001
06002
06003 if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0))
06004 return omit_one_operand (type, arg0, arg1);
06005 goto truth_andor;
06006
06007 case TRUTH_XOR_EXPR:
06008
06009 if (integer_zerop (arg0))
06010 return non_lvalue (convert (type, arg1));
06011 if (integer_zerop (arg1))
06012 return non_lvalue (convert (type, arg0));
06013
06014 if (integer_onep (arg0))
06015 return non_lvalue (convert (type, invert_truthvalue (arg1)));
06016 if (integer_onep (arg1))
06017 return non_lvalue (convert (type, invert_truthvalue (arg0)));
06018 return t;
06019
06020 case EQ_EXPR:
06021 case NE_EXPR:
06022 case LT_EXPR:
06023 case GT_EXPR:
06024 case LE_EXPR:
06025 case GE_EXPR:
06026
06027 if ((TREE_CODE (arg0) == INTEGER_CST
06028 && TREE_CODE (arg1) != INTEGER_CST)
06029 || (TREE_CODE (arg0) == REAL_CST
06030 && TREE_CODE (arg0) != REAL_CST))
06031 {
06032 if (t == orig_t)
06033 t = copy_node (t);
06034 TREE_OPERAND (t, 0) = arg1;
06035 TREE_OPERAND (t, 1) = arg0;
06036 arg0 = TREE_OPERAND (t, 0);
06037 arg1 = TREE_OPERAND (t, 1);
06038 code = swap_tree_comparison (code);
06039 TREE_SET_CODE (t, code);
06040 }
06041
06042 if (FLOAT_TYPE_P (TREE_TYPE (arg0)))
06043 {
06044
06045 if (TREE_CODE (arg0) == NEGATE_EXPR
06046 && TREE_CODE (arg1) == NEGATE_EXPR)
06047 return fold (build (code, type, TREE_OPERAND (arg1, 0),
06048 TREE_OPERAND (arg0, 0)));
06049
06050 if (TREE_CODE (arg0) == NEGATE_EXPR && TREE_CODE (arg1) == REAL_CST)
06051 return
06052 fold (build
06053 (swap_tree_comparison (code), type,
06054 TREE_OPERAND (arg0, 0),
06055 build_real (TREE_TYPE (arg1),
06056 REAL_VALUE_NEGATE (TREE_REAL_CST (arg1)))));
06057
06058
06059 if (TREE_CODE (arg1) == REAL_CST
06060 && REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (arg1)))
06061 return fold (build (code, type, arg0,
06062 build_real (TREE_TYPE (arg1), dconst0)));
06063
06064
06065
06066
06067
06068 if (flag_unsafe_math_optimizations
06069 && TREE_CODE (arg1) == REAL_CST
06070 && (TREE_CODE (arg0) == PLUS_EXPR
06071 || TREE_CODE (arg0) == MINUS_EXPR)
06072 && TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST
06073 && 0 != (tem = const_binop (TREE_CODE (arg0) == PLUS_EXPR
06074 ? MINUS_EXPR : PLUS_EXPR,
06075 arg1, TREE_OPERAND (arg0, 1), 0))
06076 && ! TREE_CONSTANT_OVERFLOW (tem))
06077 return fold (build (code, type, TREE_OPERAND (arg0, 0), tem));
06078 }
06079
06080
06081
06082
06083 {
06084 tree constop = 0, varop = NULL_TREE;
06085 int constopnum = -1;
06086
06087 if (TREE_CONSTANT (arg1))
06088 constopnum = 1, constop = arg1, varop = arg0;
06089 if (TREE_CONSTANT (arg0))
06090 constopnum = 0, constop = arg0, varop = arg1;
06091
06092 if (constop && TREE_CODE (varop) == POSTINCREMENT_EXPR)
06093 {
06094
06095
06096
06097
06098 if (POINTER_TYPE_P (TREE_TYPE (varop))
06099 || (! FLOAT_TYPE_P (TREE_TYPE (varop))
06100 && (code == EQ_EXPR || code == NE_EXPR)))
06101 {
06102 tree newconst
06103 = fold (build (PLUS_EXPR, TREE_TYPE (varop),
06104 constop, TREE_OPERAND (varop, 1)));
06105
06106
06107
06108
06109
06110
06111 varop = build (PREINCREMENT_EXPR, TREE_TYPE (varop),
06112 TREE_OPERAND (varop, 0),
06113 TREE_OPERAND (varop, 1));
06114
06115
06116
06117 if (TREE_CODE (TREE_OPERAND (varop, 0)) == COMPONENT_REF
06118 && DECL_BIT_FIELD(TREE_OPERAND
06119 (TREE_OPERAND (varop, 0), 1)))
06120 {
06121 int size
06122 = TREE_INT_CST_LOW (DECL_SIZE
06123 (TREE_OPERAND
06124 (TREE_OPERAND (varop, 0), 1)));
06125 tree mask, unsigned_type;
06126 unsigned int precision;
06127 tree folded_compare;
06128
06129
06130
06131
06132 if (constopnum == 0)
06133 folded_compare = fold (build (code, type, constop,
06134 TREE_OPERAND (varop, 0)));
06135 else
06136 folded_compare = fold (build (code, type,
06137 TREE_OPERAND (varop, 0),
06138 constop));
06139 if (integer_zerop (folded_compare)
06140 || integer_onep (folded_compare))
06141 return omit_one_operand (type, folded_compare, varop);
06142
06143 unsigned_type = (*lang_hooks.types.type_for_size)(size, 1);
06144 precision = TYPE_PRECISION (unsigned_type);
06145 mask = build_int_2 (~0, ~0);
06146 TREE_TYPE (mask) = unsigned_type;
06147 force_fit_type (mask, 0);
06148 mask = const_binop (RSHIFT_EXPR, mask,
06149 size_int (precision - size), 0);
06150 newconst = fold (build (BIT_AND_EXPR,
06151 TREE_TYPE (varop), newconst,
06152 convert (TREE_TYPE (varop),
06153 mask)));
06154 }
06155
06156 t = build (code, type,
06157 (constopnum == 0) ? newconst : varop,
06158 (constopnum == 1) ? newconst : varop);
06159 return t;
06160 }
06161 }
06162 else if (constop && TREE_CODE (varop) == POSTDECREMENT_EXPR)
06163 {
06164 if (POINTER_TYPE_P (TREE_TYPE (varop))
06165 || (! FLOAT_TYPE_P (TREE_TYPE (varop))
06166 && (code == EQ_EXPR || code == NE_EXPR)))
06167 {
06168 tree newconst
06169 = fold (build (MINUS_EXPR, TREE_TYPE (varop),
06170 constop, TREE_OPERAND (varop, 1)));
06171
06172
06173
06174
06175
06176
06177 varop = build (PREDECREMENT_EXPR, TREE_TYPE (varop),
06178 TREE_OPERAND (varop, 0),
06179 TREE_OPERAND (varop, 1));
06180
06181 if (TREE_CODE (TREE_OPERAND (varop, 0)) == COMPONENT_REF
06182 && DECL_BIT_FIELD(TREE_OPERAND
06183 (TREE_OPERAND (varop, 0), 1)))
06184 {
06185 int size
06186 = TREE_INT_CST_LOW (DECL_SIZE
06187 (TREE_OPERAND
06188 (TREE_OPERAND (varop, 0), 1)));
06189 tree mask, unsigned_type;
06190 unsigned int precision;
06191 tree folded_compare;
06192
06193 if (constopnum == 0)
06194 folded_compare = fold (build (code, type, constop,
06195 TREE_OPERAND (varop, 0)));
06196 else
06197 folded_compare = fold (build (code, type,
06198 TREE_OPERAND (varop, 0),
06199 constop));
06200 if (integer_zerop (folded_compare)
06201 || integer_onep (folded_compare))
06202 return omit_one_operand (type, folded_compare, varop);
06203
06204 unsigned_type = (*lang_hooks.types.type_for_size)(size, 1);
06205 precision = TYPE_PRECISION (unsigned_type);
06206 mask = build_int_2 (~0, ~0);
06207 TREE_TYPE (mask) = TREE_TYPE (varop);
06208 force_fit_type (mask, 0);
06209 mask = const_binop (RSHIFT_EXPR, mask,
06210 size_int (precision - size), 0);
06211 newconst = fold (build (BIT_AND_EXPR,
06212 TREE_TYPE (varop), newconst,
06213 convert (TREE_TYPE (varop),
06214 mask)));
06215 }
06216
06217 t = build (code, type,
06218 (constopnum == 0) ? newconst : varop,
06219 (constopnum == 1) ? newconst : varop);
06220 return t;
06221 }
06222 }
06223 }
06224
06225
06226
06227
06228 if (TREE_CODE (arg1) == INTEGER_CST
06229 && TREE_CODE (arg0) != INTEGER_CST
06230 && tree_int_cst_sgn (arg1) > 0)
06231 {
06232 switch (code)
06233 {
06234 case GE_EXPR:
06235 code = GT_EXPR;
06236 arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
06237 t = build (code, type, TREE_OPERAND (t, 0), arg1);
06238 break;
06239
06240 case LT_EXPR:
06241 code = LE_EXPR;
06242 arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
06243 t = build (code, type, TREE_OPERAND (t, 0), arg1);
06244 break;
06245
06246 default:
06247 break;
06248 }
06249 }
06250
06251
06252
06253 {
06254 int width = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (arg1)));
06255
06256 if (TREE_CODE (arg1) == INTEGER_CST
06257 && ! TREE_CONSTANT_OVERFLOW (arg1)
06258 && width <= HOST_BITS_PER_WIDE_INT
06259 && (INTEGRAL_TYPE_P (TREE_TYPE (arg1))
06260 || POINTER_TYPE_P (TREE_TYPE (arg1))))
06261 {
06262 unsigned HOST_WIDE_INT signed_max;
06263 unsigned HOST_WIDE_INT max, min;
06264
06265 signed_max = ((unsigned HOST_WIDE_INT) 1 << (width - 1)) - 1;
06266
06267 if (TREE_UNSIGNED (TREE_TYPE (arg1)))
06268 {
06269 max = ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1;
06270 min = 0;
06271 }
06272 else
06273 {
06274 max = signed_max;
06275 min = ((unsigned HOST_WIDE_INT) -1 << (width - 1));
06276 }
06277
06278 if (TREE_INT_CST_HIGH (arg1) == 0
06279 && TREE_INT_CST_LOW (arg1) == max)
06280 switch (code)
06281 {
06282 case GT_EXPR:
06283 return omit_one_operand (type,
06284 convert (type, integer_zero_node),
06285 arg0);
06286 case GE_EXPR:
06287 code = EQ_EXPR;
06288 if (t == orig_t)
06289 t = copy_node (t);
06290 TREE_SET_CODE (t, EQ_EXPR);
06291 break;
06292 case LE_EXPR:
06293 return omit_one_operand (type,
06294 convert (type, integer_one_node),
06295 arg0);
06296 case LT_EXPR:
06297 code = NE_EXPR;
06298 if (t == orig_t)
06299 t = copy_node (t);
06300 TREE_SET_CODE (t, NE_EXPR);
06301 break;
06302
06303
06304
06305
06306 default:
06307 break;
06308 }
06309 else if (TREE_INT_CST_HIGH (arg1) == 0
06310 && TREE_INT_CST_LOW (arg1) == max - 1)
06311 switch (code)
06312 {
06313 case GT_EXPR:
06314 code = EQ_EXPR;
06315 arg1 = const_binop (PLUS_EXPR, arg1, integer_one_node, 0);
06316 t = build (code, type, TREE_OPERAND (t, 0), arg1);
06317 break;
06318 case LE_EXPR:
06319 code = NE_EXPR;
06320 arg1 = const_binop (PLUS_EXPR, arg1, integer_one_node, 0);
06321 t = build (code, type, TREE_OPERAND (t, 0), arg1);
06322 break;
06323 default:
06324 break;
06325 }
06326 else if (TREE_INT_CST_HIGH (arg1) == (min ? -1 : 0)
06327 && TREE_INT_CST_LOW (arg1) == min)
06328 switch (code)
06329 {
06330 case LT_EXPR:
06331 return omit_one_operand (type,
06332 convert (type, integer_zero_node),
06333 arg0);
06334 case LE_EXPR:
06335 code = EQ_EXPR;
06336 if (t == orig_t)
06337 t = copy_node (t);
06338 TREE_SET_CODE (t, EQ_EXPR);
06339 break;
06340
06341 case GE_EXPR:
06342 return omit_one_operand (type,
06343 convert (type, integer_one_node),
06344 arg0);
06345 case GT_EXPR:
06346 code = NE_EXPR;
06347 if (t == orig_t)
06348 t = copy_node (t);
06349 TREE_SET_CODE (t, NE_EXPR);
06350 break;
06351
06352 default:
06353 break;
06354 }
06355 else if (TREE_INT_CST_HIGH (arg1) == (min ? -1 : 0)
06356 && TREE_INT_CST_LOW (arg1) == min + 1)
06357 switch (code)
06358 {
06359 case GE_EXPR:
06360 code = NE_EXPR;
06361 arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
06362 t = build (code, type, TREE_OPERAND (t, 0), arg1);
06363 break;
06364 case LT_EXPR:
06365 code = EQ_EXPR;
06366 arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
06367 t = build (code, type, TREE_OPERAND (t, 0), arg1);
06368 break;
06369 default:
06370 break;
06371 }
06372
06373 else if (TREE_INT_CST_HIGH (arg1) == 0
06374 && TREE_INT_CST_LOW (arg1) == signed_max
06375 && TREE_UNSIGNED (TREE_TYPE (arg1))
06376
06377 && INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
06378 {
06379
06380
06381 if (code == LE_EXPR || code == GT_EXPR)
06382 {
06383 tree st0, st1;
06384 st0 = (*lang_hooks.types.signed_type) (TREE_TYPE (arg0));
06385 st1 = (*lang_hooks.types.signed_type) (TREE_TYPE (arg1));
06386 return fold
06387 (build (code == LE_EXPR ? GE_EXPR: LT_EXPR,
06388 type, convert (st0, arg0),
06389 convert (st1, integer_zero_node)));
06390 }
06391 }
06392 }
06393 }
06394
06395
06396
06397
06398 if ((code == EQ_EXPR || code == NE_EXPR)
06399 && TREE_CODE (arg1) == INTEGER_CST
06400 && (TREE_CODE (arg0) == PLUS_EXPR
06401 || TREE_CODE (arg0) == MINUS_EXPR)
06402 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
06403 && 0 != (tem = const_binop (TREE_CODE (arg0) == PLUS_EXPR
06404 ? MINUS_EXPR : PLUS_EXPR,
06405 arg1, TREE_OPERAND (arg0, 1), 0))
06406 && ! TREE_CONSTANT_OVERFLOW (tem))
06407 return fold (build (code, type, TREE_OPERAND (arg0, 0), tem));
06408
06409
06410 else if ((code == EQ_EXPR || code == NE_EXPR)
06411 && TREE_CODE (arg0) == NEGATE_EXPR
06412 && TREE_CODE (arg1) == INTEGER_CST
06413 && 0 != (tem = negate_expr (arg1))
06414 && TREE_CODE (tem) == INTEGER_CST
06415 && ! TREE_CONSTANT_OVERFLOW (tem))
06416 return fold (build (code, type, TREE_OPERAND (arg0, 0), tem));
06417
06418
06419
06420 else if ((code == NE_EXPR || code == EQ_EXPR)
06421 && integer_zerop (arg1) && TREE_CODE (arg0) == MINUS_EXPR)
06422 return fold (build (code, type,
06423 TREE_OPERAND (arg0, 0), TREE_OPERAND (arg0, 1)));
06424
06425
06426
06427
06428 else if (TREE_CODE (TREE_TYPE (arg0)) == INTEGER_TYPE
06429 && TREE_CODE (arg0) == NOP_EXPR
06430 && (tem = get_unwidened (arg0, NULL_TREE)) != arg0
06431 && (t1 = get_unwidened (arg1, TREE_TYPE (tem))) != 0
06432 && (TREE_TYPE (t1) == TREE_TYPE (tem)
06433 || (TREE_CODE (t1) == INTEGER_CST
06434 #ifdef KEY
06435 && (TREE_UNSIGNED (TREE_TYPE (tem)) ||
06436 !TREE_UNSIGNED (TREE_TYPE (t1)))
06437 #endif
06438 && int_fits_type_p (t1, TREE_TYPE (tem)))))
06439 return fold (build (code, type, tem, convert (TREE_TYPE (tem), t1)));
06440
06441
06442
06443 else if (TREE_CODE (arg1) == INTEGER_CST
06444 && (TREE_CODE (arg0) == MIN_EXPR
06445 || TREE_CODE (arg0) == MAX_EXPR)
06446 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
06447 return optimize_minmax_comparison (t);
06448
06449
06450
06451
06452
06453
06454 else if (code == LE_EXPR && TREE_CODE (arg1) == INTEGER_CST
06455 && TREE_CODE (arg0) == ABS_EXPR
06456 && ! TREE_SIDE_EFFECTS (arg0)
06457 && (0 != (tem = negate_expr (arg1)))
06458 && TREE_CODE (tem) == INTEGER_CST
06459 && ! TREE_CONSTANT_OVERFLOW (tem))
06460 return fold (build (TRUTH_ANDIF_EXPR, type,
06461 build (GE_EXPR, type, TREE_OPERAND (arg0, 0), tem),
06462 build (LE_EXPR, type,
06463 TREE_OPERAND (arg0, 0), arg1)));
06464
06465
06466
06467
06468
06469
06470 if (
06471 #ifdef KEY
06472
06473
06474
06475 flag_honor_shift == 0 &&
06476 #endif
06477 integer_zerop (arg1) && (code == EQ_EXPR || code == NE_EXPR)
06478 && TREE_CODE (arg0) == BIT_AND_EXPR)
06479 {
06480 if (TREE_CODE (TREE_OPERAND (arg0, 0)) == LSHIFT_EXPR
06481 && integer_onep (TREE_OPERAND (TREE_OPERAND (arg0, 0), 0)))
06482 return
06483 fold (build (code, type,
06484 build (BIT_AND_EXPR, TREE_TYPE (arg0),
06485 build (RSHIFT_EXPR,
06486 TREE_TYPE (TREE_OPERAND (arg0, 0)),
06487 TREE_OPERAND (arg0, 1),
06488 TREE_OPERAND (TREE_OPERAND (arg0, 0), 1)),
06489 convert (TREE_TYPE (arg0),
06490 integer_one_node)),
06491 arg1));
06492 else if (TREE_CODE (TREE_OPERAND (arg0, 1)) == LSHIFT_EXPR
06493 && integer_onep (TREE_OPERAND (TREE_OPERAND (arg0, 1), 0)))
06494 return
06495 fold (build (code, type,
06496 build (BIT_AND_EXPR, TREE_TYPE (arg0),
06497 build (RSHIFT_EXPR,
06498 TREE_TYPE (TREE_OPERAND (arg0, 1)),
06499 TREE_OPERAND (arg0, 0),
06500 TREE_OPERAND (TREE_OPERAND (arg0, 1), 1)),
06501 convert (TREE_TYPE (arg0),
06502 integer_one_node)),
06503 arg1));
06504 }
06505
06506
06507
06508
06509 if ((code == NE_EXPR || code == EQ_EXPR)
06510 && integer_zerop (arg1)
06511 && ! TREE_UNSIGNED (TREE_TYPE (arg0))
06512 && (TREE_CODE (arg0) == TRUNC_MOD_EXPR
06513 || TREE_CODE (arg0) == CEIL_MOD_EXPR
06514 || TREE_CODE (arg0) == FLOOR_MOD_EXPR
06515 || TREE_CODE (arg0) == ROUND_MOD_EXPR)
06516 && integer_pow2p (TREE_OPERAND (arg0, 1)))
06517 {
06518 tree newtype = (*lang_hooks.types.unsigned_type) (TREE_TYPE (arg0));
06519 tree newmod = build (TREE_CODE (arg0), newtype,
06520 convert (newtype, TREE_OPERAND (arg0, 0)),
06521 convert (newtype, TREE_OPERAND (arg0, 1)));
06522
06523 return build (code, type, newmod, convert (newtype, arg1));
06524 }
06525
06526
06527
06528 if (code == NE_EXPR && integer_zerop (arg1)
06529 && TREE_CODE (arg0) == BIT_AND_EXPR
06530 && integer_onep (TREE_OPERAND (arg0, 1)))
06531 return convert (type, arg0);
06532
06533
06534
06535 if ((code == EQ_EXPR || code == NE_EXPR)
06536 && TREE_CODE (arg0) == BIT_AND_EXPR
06537 && integer_pow2p (TREE_OPERAND (arg0, 1))
06538 && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0))
06539 return fold (build (code == EQ_EXPR ? NE_EXPR : EQ_EXPR, type,
06540 arg0, integer_zero_node));
06541
06542
06543
06544 if ((code == EQ_EXPR || code == NE_EXPR)
06545 && TREE_CODE (arg0) == BIT_AND_EXPR
06546 && integer_zerop (arg1))
06547 {
06548 tree arg00 = sign_bit_p (TREE_OPERAND (arg0, 0),
06549 TREE_OPERAND (arg0, 1));
06550 if (arg00 != NULL_TREE)
06551 {
06552 tree stype = (*lang_hooks.types.signed_type) (TREE_TYPE (arg00));
06553 return fold (build (code == EQ_EXPR ? GE_EXPR : LT_EXPR, type,
06554 convert (stype, arg00),
06555 convert (stype, integer_zero_node)));
06556 }
06557 }
06558
06559
06560
06561 if ((code == LT_EXPR || code == GE_EXPR)
06562 && TREE_UNSIGNED (TREE_TYPE (arg0))
06563 && TREE_CODE (arg1) == LSHIFT_EXPR
06564 && integer_onep (TREE_OPERAND (arg1, 0)))
06565 return build (code == LT_EXPR ? EQ_EXPR : NE_EXPR, type,
06566 build (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
06567 TREE_OPERAND (arg1, 1)),
06568 convert (TREE_TYPE (arg0), integer_zero_node));
06569
06570 else if ((code == LT_EXPR || code == GE_EXPR)
06571 && TREE_UNSIGNED (TREE_TYPE (arg0))
06572 && (TREE_CODE (arg1) == NOP_EXPR
06573 || TREE_CODE (arg1) == CONVERT_EXPR)
06574 && TREE_CODE (TREE_OPERAND (arg1, 0)) == LSHIFT_EXPR
06575 && integer_onep (TREE_OPERAND (TREE_OPERAND (arg1, 0), 0)))
06576 return
06577 build (code == LT_EXPR ? EQ_EXPR : NE_EXPR, type,
06578 convert (TREE_TYPE (arg0),
06579 build (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
06580 TREE_OPERAND (TREE_OPERAND (arg1, 0), 1))),
06581 convert (TREE_TYPE (arg0), integer_zero_node));
06582
06583
06584
06585 if (operand_equal_p (arg0, arg1, 0))
06586 {
06587 switch (code)
06588 {
06589 case EQ_EXPR:
06590 case GE_EXPR:
06591 case LE_EXPR:
06592 if (! FLOAT_TYPE_P (TREE_TYPE (arg0)))
06593 return constant_boolean_node (1, type);
06594 code = EQ_EXPR;
06595 if (t == orig_t)
06596 t = copy_node (t);
06597 TREE_SET_CODE (t, code);
06598 break;
06599
06600 case NE_EXPR:
06601
06602 if (FLOAT_TYPE_P (TREE_TYPE (arg0)))
06603 break;
06604
06605 case GT_EXPR:
06606 case LT_EXPR:
06607 return constant_boolean_node (0, type);
06608 default:
06609 abort ();
06610 }
06611 }
06612
06613
06614
06615
06616
06617
06618
06619
06620
06621
06622
06623
06624
06625
06626 if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg0) != INTEGER_CST)
06627 {
06628 tree cval1 = 0, cval2 = 0;
06629 int save_p = 0;
06630
06631 if (twoval_comparison_p (arg0, &cval1, &cval2, &save_p)
06632
06633
06634 && cval1 != 0 && cval2 != 0
06635 && ! (TREE_CONSTANT (cval1) && TREE_CONSTANT (cval2))
06636 && TREE_TYPE (cval1) == TREE_TYPE (cval2)
06637 && INTEGRAL_TYPE_P (TREE_TYPE (cval1))
06638 && TYPE_MAX_VALUE (TREE_TYPE (cval1))
06639 && TYPE_MAX_VALUE (TREE_TYPE (cval2))
06640 && ! operand_equal_p (TYPE_MIN_VALUE (TREE_TYPE (cval1)),
06641 TYPE_MAX_VALUE (TREE_TYPE (cval2)), 0))
06642 {
06643 tree maxval = TYPE_MAX_VALUE (TREE_TYPE (cval1));
06644 tree minval = TYPE_MIN_VALUE (TREE_TYPE (cval1));
06645
06646
06647
06648
06649 tree high_result
06650 = fold (build (code, type,
06651 eval_subst (arg0, cval1, maxval, cval2, minval),
06652 arg1));
06653 tree equal_result
06654 = fold (build (code, type,
06655 eval_subst (arg0, cval1, maxval, cval2, maxval),
06656 arg1));
06657 tree low_result
06658 = fold (build (code, type,
06659 eval_subst (arg0, cval1, minval, cval2, maxval),
06660 arg1));
06661
06662
06663
06664
06665
06666 if ((integer_zerop (high_result)
06667 || integer_onep (high_result))
06668 && (integer_zerop (equal_result)
06669 || integer_onep (equal_result))
06670 && (integer_zerop (low_result)
06671 || integer_onep (low_result)))
06672 {
06673
06674
06675 switch ((integer_onep (high_result) * 4)
06676 + (integer_onep (equal_result) * 2)
06677 + integer_onep (low_result))
06678 {
06679 case 0:
06680
06681 return omit_one_operand (type, integer_zero_node, arg0);
06682 case 1:
06683 code = LT_EXPR;
06684 break;
06685 case 2:
06686 code = EQ_EXPR;
06687 break;
06688 case 3:
06689 code = LE_EXPR;
06690 break;
06691 case 4:
06692 code = GT_EXPR;
06693 break;
06694 case 5:
06695 code = NE_EXPR;
06696 break;
06697 case 6:
06698 code = GE_EXPR;
06699 break;
06700 case 7:
06701
06702 return omit_one_operand (type, integer_one_node, arg0);
06703 }
06704
06705 t = build (code, type, cval1, cval2);
06706 if (save_p)
06707 return save_expr (t);
06708 else
06709 return fold (t);
06710 }
06711 }
06712 }
06713
06714
06715 if (((TREE_CODE (arg0) == COMPONENT_REF
06716 && (*lang_hooks.can_use_bit_fields_p) ())
06717 || TREE_CODE (arg0) == BIT_FIELD_REF)
06718 && (code == EQ_EXPR || code == NE_EXPR)
06719
06720
06721 && (optimize || TREE_CODE (arg1) == INTEGER_CST))
06722 {
06723 t1 = optimize_bit_field_compare (code, type, arg0, arg1);
06724 return t1 ? t1 : t;
06725 }
06726
06727
06728
06729
06730
06731 if ((code == EQ_EXPR || code == NE_EXPR)
06732 && TREE_CODE (TREE_TYPE (arg0)) == COMPLEX_TYPE
06733 && (TREE_CODE (arg0) == COMPLEX_EXPR
06734 || TREE_CODE (arg1) == COMPLEX_EXPR
06735 || TREE_CODE (arg0) == COMPLEX_CST
06736 || TREE_CODE (arg1) == COMPLEX_CST))
06737 {
06738 tree subtype = TREE_TYPE (TREE_TYPE (arg0));
06739 tree real0, imag0, real1, imag1;
06740
06741 arg0 = save_expr (arg0);
06742 arg1 = save_expr (arg1);
06743 real0 = fold (build1 (REALPART_EXPR, subtype, arg0));
06744 imag0 = fold (build1 (IMAGPART_EXPR, subtype, arg0));
06745 real1 = fold (build1 (REALPART_EXPR, subtype, arg1));
06746 imag1 = fold (build1 (IMAGPART_EXPR, subtype, arg1));
06747
06748 return fold (build ((code == EQ_EXPR ? TRUTH_ANDIF_EXPR
06749 : TRUTH_ORIF_EXPR),
06750 type,
06751 fold (build (code, type, real0, real1)),
06752 fold (build (code, type, imag0, imag1))));
06753 }
06754
06755
06756
06757
06758
06759
06760
06761 if ((code == EQ_EXPR || code == NE_EXPR)
06762 && integer_zerop (arg1)
06763 && TREE_CODE (arg0) == CALL_EXPR
06764 && TREE_CODE (TREE_OPERAND (arg0, 0)) == ADDR_EXPR)
06765 {
06766 tree fndecl = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
06767 tree arglist;
06768
06769 if (TREE_CODE (fndecl) == FUNCTION_DECL
06770 && DECL_BUILT_IN (fndecl)
06771 && DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_MD
06772 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STRLEN
06773 && (arglist = TREE_OPERAND (arg0, 1))
06774 && TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) == POINTER_TYPE
06775 && ! TREE_CHAIN (arglist))
06776 return fold (build (code, type,
06777 build1 (INDIRECT_REF, char_type_node,
06778 TREE_VALUE(arglist)),
06779 integer_zero_node));
06780 }
06781
06782
06783
06784
06785
06786
06787
06788
06789
06790
06791
06792 if (code == LE_EXPR || code == GT_EXPR)
06793 {
06794 tem = arg0, arg0 = arg1, arg1 = tem;
06795 code = swap_tree_comparison (code);
06796 }
06797
06798
06799
06800
06801 t1 = NULL_TREE;
06802 invert = 0;
06803 if (code == NE_EXPR || code == GE_EXPR)
06804 {
06805 invert = 1;
06806 code = invert_tree_comparison (code);
06807 }
06808
06809
06810
06811 if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
06812 {
06813 if (code == EQ_EXPR)
06814 t1 = build_int_2 (tree_int_cst_equal (arg0, arg1), 0);
06815 else
06816 t1 = build_int_2 ((TREE_UNSIGNED (TREE_TYPE (arg0))
06817 ? INT_CST_LT_UNSIGNED (arg0, arg1)
06818 : INT_CST_LT (arg0, arg1)),
06819 0);
06820 }
06821
06822 #if 0
06823
06824
06825
06826
06827 else if (TREE_CODE (arg1) == INTEGER_CST
06828 && !integer_zerop (arg1)
06829 && TREE_CONSTANT (arg0)
06830 && TREE_CODE (arg0) == ADDR_EXPR
06831 && code == EQ_EXPR)
06832 t1 = build_int_2 (0, 0);
06833 #endif
06834
06835 else if (TREE_CODE (arg0) == REAL_CST && TREE_CODE (arg1) == REAL_CST)
06836 {
06837
06838
06839
06840
06841
06842
06843
06844 if (REAL_VALUE_ISNAN (TREE_REAL_CST (arg0))
06845 || REAL_VALUE_ISNAN (TREE_REAL_CST (arg1)))
06846 t1 = build_int_2 (invert && code == LT_EXPR, 0);
06847
06848 else if (code == EQ_EXPR)
06849 t1 = build_int_2 (REAL_VALUES_EQUAL (TREE_REAL_CST (arg0),
06850 TREE_REAL_CST (arg1)),
06851 0);
06852 else
06853 t1 = build_int_2 (REAL_VALUES_LESS (TREE_REAL_CST (arg0),
06854 TREE_REAL_CST (arg1)),
06855 0);
06856 }
06857
06858 if (t1 == NULL_TREE)
06859 return t;
06860
06861 if (invert)
06862 TREE_INT_CST_LOW (t1) ^= 1;
06863
06864 TREE_TYPE (t1) = type;
06865 if (TREE_CODE (type) == BOOLEAN_TYPE)
06866 return (*lang_hooks.truthvalue_conversion) (t1);
06867 return t1;
06868
06869 case COND_EXPR:
06870
06871
06872 if (TREE_CODE (arg0) == INTEGER_CST)
06873 return pedantic_non_lvalue
06874 (TREE_OPERAND (t, (integer_zerop (arg0) ? 2 : 1)));
06875 else if (operand_equal_p (arg1, TREE_OPERAND (expr, 2), 0))
06876 return pedantic_omit_one_operand (type, arg1, arg0);
06877
06878
06879
06880
06881
06882
06883 if (integer_zerop (arg1)
06884 || (TREE_CONSTANT (arg1) && ! TREE_CONSTANT (TREE_OPERAND (t, 2)))
06885 || (TREE_CODE_CLASS (TREE_CODE (arg0)) == '<'
06886 && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0),
06887 TREE_OPERAND (t, 2),
06888 TREE_OPERAND (arg0, 1))))
06889 {
06890
06891
06892
06893 tem = invert_truthvalue (arg0);
06894
06895 if (TREE_CODE (tem) != TRUTH_NOT_EXPR)
06896 {
06897 t = build (code, type, tem,
06898 TREE_OPERAND (t, 2), TREE_OPERAND (t, 1));
06899 arg0 = tem;
06900
06901 arg1 = TREE_OPERAND (t, 1);
06902 STRIP_NOPS (arg1);
06903 }
06904 }
06905
06906
06907
06908
06909
06910
06911 if (TREE_CODE_CLASS (TREE_CODE (arg0)) == '<'
06912 && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0),
06913 arg1, TREE_OPERAND (arg0, 1))
06914 && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
06915 {
06916 tree arg2 = TREE_OPERAND (t, 2);
06917 enum tree_code comp_code = TREE_CODE (arg0);
06918
06919 STRIP_NOPS (arg2);
06920
06921
06922
06923
06924
06925
06926
06927
06928
06929
06930
06931
06932
06933
06934
06935
06936
06937
06938
06939
06940 if ((FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (arg0, 1)))
06941 ? real_zerop (TREE_OPERAND (arg0, 1))
06942 : integer_zerop (TREE_OPERAND (arg0, 1)))
06943 && TREE_CODE (arg2) == NEGATE_EXPR
06944 && operand_equal_p (TREE_OPERAND (arg2, 0), arg1, 0))
06945 switch (comp_code)
06946 {
06947 case EQ_EXPR:
06948 return
06949 pedantic_non_lvalue
06950 (convert (type,
06951 negate_expr
06952 (convert (TREE_TYPE (TREE_OPERAND (t, 1)),
06953 arg1))));
06954 case NE_EXPR:
06955 return pedantic_non_lvalue (convert (type, arg1));
06956 case GE_EXPR:
06957 case GT_EXPR:
06958 if (TREE_UNSIGNED (TREE_TYPE (arg1)))
06959 arg1 = convert ((*lang_hooks.types.signed_type)
06960 (TREE_TYPE (arg1)), arg1);
06961 return pedantic_non_lvalue
06962 (convert (type, fold (build1 (ABS_EXPR,
06963 TREE_TYPE (arg1), arg1))));
06964 case LE_EXPR:
06965 case LT_EXPR:
06966 if (TREE_UNSIGNED (TREE_TYPE (arg1)))
06967 arg1 = convert ((lang_hooks.types.signed_type)
06968 (TREE_TYPE (arg1)), arg1);
06969 return pedantic_non_lvalue
06970 (negate_expr (convert (type,
06971 fold (build1 (ABS_EXPR,
06972 TREE_TYPE (arg1),
06973 arg1)))));
06974 default:
06975 abort ();
06976 }
06977
06978
06979
06980
06981
06982
06983 if (integer_zerop (TREE_OPERAND (arg0, 1)) && integer_zerop (arg2))
06984 {
06985 if (comp_code == NE_EXPR)
06986 return pedantic_non_lvalue (convert (type, arg1));
06987 else if (comp_code == EQ_EXPR)
06988 return pedantic_non_lvalue (convert (type, integer_zero_node));
06989 }
06990
06991
06992
06993
06994
06995
06996
06997
06998
06999
07000
07001
07002
07003
07004
07005
07006
07007
07008
07009
07010
07011
07012
07013
07014
07015
07016
07017 if (operand_equal_for_comparison_p (TREE_OPERAND (arg0, 1),
07018 arg2, TREE_OPERAND (arg0, 0)))
07019 {
07020 tree comp_op0 = TREE_OPERAND (arg0, 0);
07021 tree comp_op1 = TREE_OPERAND (arg0, 1);
07022 tree comp_type = TREE_TYPE (comp_op0);
07023
07024
07025 if (TYPE_MAIN_VARIANT (comp_type) == TYPE_MAIN_VARIANT (type))
07026 comp_type = type;
07027
07028 switch (comp_code)
07029 {
07030 case EQ_EXPR:
07031 return pedantic_non_lvalue (convert (type, arg2));
07032 case NE_EXPR:
07033 return pedantic_non_lvalue (convert (type, arg1));
07034 case LE_EXPR:
07035 case LT_EXPR:
07036
07037
07038
07039
07040 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))))
07041 return pedantic_non_lvalue
07042 (convert (type, fold (build (MIN_EXPR, comp_type,
07043 (comp_code == LE_EXPR
07044 ? comp_op0 : comp_op1),
07045 (comp_code == LE_EXPR
07046 ? comp_op1 : comp_op0)))));
07047 break;
07048 case GE_EXPR:
07049 case GT_EXPR:
07050 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))))
07051 return pedantic_non_lvalue
07052 (convert (type, fold (build (MAX_EXPR, comp_type,
07053 (comp_code == GE_EXPR
07054 ? comp_op0 : comp_op1),
07055 (comp_code == GE_EXPR
07056 ? comp_op1 : comp_op0)))));
07057 break;
07058 default:
07059 abort ();
07060 }
07061 }
07062
07063
07064
07065
07066
07067
07068
07069 if (INTEGRAL_TYPE_P (type)
07070 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
07071 && TREE_CODE (arg2) == INTEGER_CST)
07072 switch (comp_code)
07073 {
07074 case EQ_EXPR:
07075
07076 arg1 = convert (type, TREE_OPERAND (arg0, 1));
07077 t = build (code, type, TREE_OPERAND (t, 0), arg1,
07078 TREE_OPERAND (t, 2));
07079 break;
07080
07081 case LT_EXPR:
07082
07083 if (! operand_equal_p (arg2, TYPE_MAX_VALUE (type), 1)
07084 && operand_equal_p (TREE_OPERAND (arg0, 1),
07085 const_binop (PLUS_EXPR, arg2,
07086 integer_one_node, 0), 1))
07087 return pedantic_non_lvalue
07088 (fold (build (MIN_EXPR, type, arg1, arg2)));
07089 break;
07090
07091 case LE_EXPR:
07092
07093 if (! operand_equal_p (arg2, TYPE_MIN_VALUE (type), 1)
07094 && operand_equal_p (TREE_OPERAND (arg0, 1),
07095 const_binop (MINUS_EXPR, arg2,
07096 integer_one_node, 0), 1))
07097 return pedantic_non_lvalue
07098 (fold (build (MIN_EXPR, type, arg1, arg2)));
07099 break;
07100
07101 case GT_EXPR:
07102
07103 if (! operand_equal_p (arg2, TYPE_MIN_VALUE (type), 1)
07104 && operand_equal_p (TREE_OPERAND (arg0, 1),
07105 const_binop (MINUS_EXPR, arg2,
07106 integer_one_node, 0), 1))
07107 return pedantic_non_lvalue
07108 (fold (build (MAX_EXPR, type, arg1, arg2)));
07109 break;
07110
07111 case GE_EXPR:
07112
07113 if (! operand_equal_p (arg2, TYPE_MAX_VALUE (type), 1)
07114 && operand_equal_p (TREE_OPERAND (arg0, 1),
07115 const_binop (PLUS_EXPR, arg2,
07116 integer_one_node, 0), 1))
07117 return pedantic_non_lvalue
07118 (fold (build (MAX_EXPR, type, arg1, arg2)));
07119 break;
07120 case NE_EXPR:
07121 break;
07122 default:
07123 abort ();
07124 }
07125 }
07126
07127
07128
07129 if ((TREE_CONSTANT (arg1) || DECL_P (arg1)
07130 || TREE_CODE (arg1) == SAVE_EXPR)
07131 && ! (TREE_CONSTANT (TREE_OPERAND (t, 2))
07132 || DECL_P (TREE_OPERAND (t, 2))
07133 || TREE_CODE (TREE_OPERAND (t, 2)) == SAVE_EXPR))
07134 {
07135
07136
07137
07138 tem = invert_truthvalue (arg0);
07139
07140 if (TREE_CODE (tem) != TRUTH_NOT_EXPR)
07141 {
07142 t = build (code, type, tem,
07143 TREE_OPERAND (t, 2), TREE_OPERAND (t, 1));
07144 arg0 = tem;
07145
07146 arg1 = TREE_OPERAND (t, 1);
07147 STRIP_NOPS (arg1);
07148 }
07149 }
07150
07151
07152 if (integer_onep (TREE_OPERAND (t, 1))
07153 && integer_zerop (TREE_OPERAND (t, 2))
07154
07155
07156
07157
07158 && type == TREE_TYPE (arg0))
07159 return pedantic_non_lvalue (arg0);
07160
07161
07162
07163 if (integer_zerop (TREE_OPERAND (t, 1))
07164 && integer_onep (TREE_OPERAND (t, 2))
07165 && truth_value_p (TREE_CODE (arg0)))
07166 return pedantic_non_lvalue (convert (type,
07167 invert_truthvalue (arg0)));
07168
07169
07170
07171
07172 if (integer_zerop (TREE_OPERAND (t, 2))
07173 && TREE_CODE (arg0) == NE_EXPR
07174 && integer_zerop (TREE_OPERAND (arg0, 1))
07175 && integer_pow2p (arg1)
07176 && TREE_CODE (TREE_OPERAND (arg0, 0)) == BIT_AND_EXPR
07177 && operand_equal_p (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1),
07178 arg1, 1))
07179 return pedantic_non_lvalue (convert (type, TREE_OPERAND (arg0, 0)));
07180
07181
07182 if (integer_zerop (TREE_OPERAND (t, 2))
07183 && truth_value_p (TREE_CODE (arg0))
07184 && truth_value_p (TREE_CODE (arg1)))
07185 return pedantic_non_lvalue (fold (build (TRUTH_ANDIF_EXPR, type,
07186 arg0, arg1)));
07187
07188
07189 if (integer_onep (TREE_OPERAND (t, 2))
07190 && truth_value_p (TREE_CODE (arg0))
07191 && truth_value_p (TREE_CODE (arg1)))
07192 {
07193
07194 tem = invert_truthvalue (arg0);
07195 if (TREE_CODE (tem) != TRUTH_NOT_EXPR)
07196 return pedantic_non_lvalue (fold (build (TRUTH_ORIF_EXPR, type,
07197 tem, arg1)));
07198 }
07199
07200 return t;
07201
07202 case COMPOUND_EXPR:
07203
07204
07205 if (TREE_SIDE_EFFECTS (arg0) || pedantic)
07206 return t;
07207
07208 if (integer_zerop (arg1))
07209 return build1 (NOP_EXPR, type, arg1);
07210 return convert (type, arg1);
07211
07212 case COMPLEX_EXPR:
07213 if (wins)
07214 return build_complex (type, arg0, arg1);
07215 return t;
07216
07217 case REALPART_EXPR:
07218 if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
07219 return t;
07220 else if (TREE_CODE (arg0) == COMPLEX_EXPR)
07221 return omit_one_operand (type, TREE_OPERAND (arg0, 0),
07222 TREE_OPERAND (arg0, 1));
07223 else if (TREE_CODE (arg0) == COMPLEX_CST)
07224 return TREE_REALPART (arg0);
07225 else if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
07226 return fold (build (TREE_CODE (arg0), type,
07227 fold (build1 (REALPART_EXPR, type,
07228 TREE_OPERAND (arg0, 0))),
07229 fold (build1 (REALPART_EXPR,
07230 type, TREE_OPERAND (arg0, 1)))));
07231 return t;
07232
07233 case IMAGPART_EXPR:
07234 if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
07235 return convert (type, integer_zero_node);
07236 else if (TREE_CODE (arg0) == COMPLEX_EXPR)
07237 return omit_one_operand (type, TREE_OPERAND (arg0, 1),
07238 TREE_OPERAND (arg0, 0));
07239 else if (TREE_CODE (arg0) == COMPLEX_CST)
07240 return TREE_IMAGPART (arg0);
07241 else if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
07242 return fold (build (TREE_CODE (arg0), type,
07243 fold (build1 (IMAGPART_EXPR, type,
07244 TREE_OPERAND (arg0, 0))),
07245 fold (build1 (IMAGPART_EXPR, type,
07246 TREE_OPERAND (arg0, 1)))));
07247 return t;
07248
07249
07250
07251 case CLEANUP_POINT_EXPR:
07252 if (! has_cleanups (arg0))
07253 return TREE_OPERAND (t, 0);
07254
07255 {
07256 enum tree_code code0 = TREE_CODE (arg0);
07257 int kind0 = TREE_CODE_CLASS (code0);
07258 tree arg00 = TREE_OPERAND (arg0, 0);
07259 tree arg01;
07260
07261 if (kind0 == '1' || code0 == TRUTH_NOT_EXPR)
07262 return fold (build1 (code0, type,
07263 fold (build1 (CLEANUP_POINT_EXPR,
07264 TREE_TYPE (arg00), arg00))));
07265
07266 if (kind0 == '<' || kind0 == '2'
07267 || code0 == TRUTH_ANDIF_EXPR || code0 == TRUTH_ORIF_EXPR
07268 || code0 == TRUTH_AND_EXPR || code0 == TRUTH_OR_EXPR
07269 || code0 == TRUTH_XOR_EXPR)
07270 {
07271 arg01 = TREE_OPERAND (arg0, 1);
07272
07273 if (TREE_CONSTANT (arg00)
07274 || ((code0 == TRUTH_ANDIF_EXPR || code0 == TRUTH_ORIF_EXPR)
07275 && ! has_cleanups (arg00)))
07276 return fold (build (code0, type, arg00,
07277 fold (build1 (CLEANUP_POINT_EXPR,
07278 TREE_TYPE (arg01), arg01))));
07279
07280 if (TREE_CONSTANT (arg01))
07281 return fold (build (code0, type,
07282 fold (build1 (CLEANUP_POINT_EXPR,
07283 TREE_TYPE (arg00), arg00)),
07284 arg01));
07285 }
07286
07287 return t;
07288 }
07289
07290 case CALL_EXPR:
07291
07292 if (TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR
07293 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (expr, 0), 0))
07294 == FUNCTION_DECL)
07295 && DECL_BUILT_IN (TREE_OPERAND (TREE_OPERAND (expr, 0), 0)))
07296 {
07297 tree tmp = fold_builtin (expr);
07298 if (tmp)
07299 return tmp;
07300 }
07301 return t;
07302
07303 default:
07304 return t;
07305 }
07306 }
07307
07308 #ifdef ENABLE_FOLD_CHECKING
07309 #undef fold
07310
07311 static void fold_checksum_tree PARAMS ((tree, struct md5_ctx *, htab_t));
07312 static void fold_check_failed PARAMS ((tree, tree));
07313 void print_fold_checksum PARAMS ((tree));
07314
07315
07316
07317
07318
07319 tree
07320 fold (expr)
07321 tree expr;
07322 {
07323 tree ret;
07324 struct md5_ctx ctx;
07325 unsigned char checksum_before[16], checksum_after[16];
07326 htab_t ht;
07327
07328 ht = htab_create (32, htab_hash_pointer, htab_eq_pointer, NULL);
07329 md5_init_ctx (&ctx);
07330 fold_checksum_tree (expr, &ctx, ht);
07331 md5_finish_ctx (&ctx, checksum_before);
07332 htab_empty (ht);
07333
07334 ret = fold_1 (expr);
07335
07336 md5_init_ctx (&ctx);
07337 fold_checksum_tree (expr, &ctx, ht);
07338 md5_finish_ctx (&ctx, checksum_after);
07339 htab_delete (ht);
07340
07341 if (memcmp (checksum_before, checksum_after, 16))
07342 fold_check_failed (expr, ret);
07343
07344 return ret;
07345 }
07346
07347 void
07348 print_fold_checksum (expr)
07349 tree expr;
07350 {
07351 struct md5_ctx ctx;
07352 unsigned char checksum[16], cnt;
07353 htab_t ht;
07354
07355 ht = htab_create (32, htab_hash_pointer, htab_eq_pointer, NULL);
07356 md5_init_ctx (&ctx);
07357 fold_checksum_tree (expr, &ctx, ht);
07358 md5_finish_ctx (&ctx, checksum);
07359 htab_delete (ht);
07360 for (cnt = 0; cnt < 16; ++cnt)
07361 fprintf (stderr, "%02x", checksum[cnt]);
07362 putc ('\n', stderr);
07363 }
07364
07365 static void
07366 fold_check_failed (expr, ret)
07367 tree expr ATTRIBUTE_UNUSED;
07368 tree ret ATTRIBUTE_UNUSED;
07369 {
07370 internal_error ("fold check: original tree changed by fold");
07371 }
07372
07373 static void
07374 fold_checksum_tree (expr, ctx, ht)
07375 tree expr;
07376 struct md5_ctx *ctx;
07377 htab_t ht;
07378 {
07379 void **slot;
07380 enum tree_code code;
07381 char buf[sizeof (struct tree_decl)];
07382 int i, len;
07383
07384 if (sizeof (struct tree_exp) + 5 * sizeof (tree)
07385 > sizeof (struct tree_decl)
07386 || sizeof (struct tree_type) > sizeof (struct tree_decl))
07387 abort ();
07388 if (expr == NULL)
07389 return;
07390 slot = htab_find_slot (ht, expr, INSERT);
07391 if (*slot != NULL)
07392 return;
07393 *slot = expr;
07394 code = TREE_CODE (expr);
07395 if (code == SAVE_EXPR && SAVE_EXPR_NOPLACEHOLDER (expr))
07396 {
07397
07398 memcpy (buf, expr, tree_size (expr));
07399 expr = (tree) buf;
07400 SAVE_EXPR_NOPLACEHOLDER (expr) = 0;
07401 }
07402 else if (TREE_CODE_CLASS (code) == 'd' && DECL_ASSEMBLER_NAME_SET_P (expr))
07403 {
07404
07405 memcpy (buf, expr, tree_size (expr));
07406 expr = (tree) buf;
07407 SET_DECL_ASSEMBLER_NAME (expr, NULL);
07408 }
07409 else if (TREE_CODE_CLASS (code) == 't'
07410 && (TYPE_POINTER_TO (expr) || TYPE_REFERENCE_TO (expr)))
07411 {
07412
07413 memcpy (buf, expr, tree_size (expr));
07414 expr = (tree) buf;
07415 TYPE_POINTER_TO (expr) = NULL;
07416 TYPE_REFERENCE_TO (expr) = NULL;
07417 }
07418 md5_process_bytes (expr, tree_size (expr), ctx);
07419 fold_checksum_tree (TREE_TYPE (expr), ctx, ht);
07420 if (TREE_CODE_CLASS (code) != 't' && TREE_CODE_CLASS (code) != 'd')
07421 fold_checksum_tree (TREE_CHAIN (expr), ctx, ht);
07422 len = TREE_CODE_LENGTH (code);
07423 switch (TREE_CODE_CLASS (code))
07424 {
07425 case 'c':
07426 switch (code)
07427 {
07428 case STRING_CST:
07429 md5_process_bytes (TREE_STRING_POINTER (expr),
07430 TREE_STRING_LENGTH (expr), ctx);
07431 break;
07432 case COMPLEX_CST:
07433 fold_checksum_tree (TREE_REALPART (expr), ctx, ht);
07434 fold_checksum_tree (TREE_IMAGPART (expr), ctx, ht);
07435 break;
07436 case VECTOR_CST:
07437 fold_checksum_tree (TREE_VECTOR_CST_ELTS (expr), ctx, ht);
07438 break;
07439 default:
07440 break;
07441 }
07442 break;
07443 case 'x':
07444 switch (code)
07445 {
07446 case TREE_LIST:
07447 fold_checksum_tree (TREE_PURPOSE (expr), ctx, ht);
07448 fold_checksum_tree (TREE_VALUE (expr), ctx, ht);
07449 break;
07450 case TREE_VEC:
07451 for (i = 0; i < TREE_VEC_LENGTH (expr); ++i)
07452 fold_checksum_tree (TREE_VEC_ELT (expr, i), ctx, ht);
07453 break;
07454 default:
07455 break;
07456 }
07457 break;
07458 case 'e':
07459 switch (code)
07460 {
07461 case SAVE_EXPR: len = 2; break;
07462 case GOTO_SUBROUTINE_EXPR: len = 0; break;
07463 case RTL_EXPR: len = 0; break;
07464 case WITH_CLEANUP_EXPR: len = 2; break;
07465 default: break;
07466 }
07467
07468 case 'r':
07469 case '<':
07470 case '1':
07471 case '2':
07472 case 's':
07473 for (i = 0; i < len; ++i)
07474 fold_checksum_tree (TREE_OPERAND (expr, i), ctx, ht);
07475 break;
07476 case 'd':
07477 fold_checksum_tree (DECL_SIZE (expr), ctx, ht);
07478 fold_checksum_tree (DECL_SIZE_UNIT (expr), ctx, ht);
07479 fold_checksum_tree (DECL_NAME (expr), ctx, ht);
07480 fold_checksum_tree (DECL_CONTEXT (expr), ctx, ht);
07481 fold_checksum_tree (DECL_ARGUMENTS (expr), ctx, ht);
07482 fold_checksum_tree (DECL_RESULT_FLD (expr), ctx, ht);
07483 fold_checksum_tree (DECL_INITIAL (expr), ctx, ht);
07484 fold_checksum_tree (DECL_ABSTRACT_ORIGIN (expr), ctx, ht);
07485 fold_checksum_tree (DECL_SECTION_NAME (expr), ctx, ht);
07486 fold_checksum_tree (DECL_ATTRIBUTES (expr), ctx, ht);
07487 fold_checksum_tree (DECL_VINDEX (expr), ctx, ht);
07488 break;
07489 case 't':
07490 fold_checksum_tree (TYPE_VALUES (expr), ctx, ht);
07491 fold_checksum_tree (TYPE_SIZE (expr), ctx, ht);
07492 fold_checksum_tree (TYPE_SIZE_UNIT (expr), ctx, ht);
07493 fold_checksum_tree (TYPE_ATTRIBUTES (expr), ctx, ht);
07494 fold_checksum_tree (TYPE_NAME (expr), ctx, ht);
07495 fold_checksum_tree (TYPE_MIN_VALUE (expr), ctx, ht);
07496 fold_checksum_tree (TYPE_MAX_VALUE (expr), ctx, ht);
07497 fold_checksum_tree (TYPE_MAIN_VARIANT (expr), ctx, ht);
07498 fold_checksum_tree (TYPE_BINFO (expr), ctx, ht);
07499 fold_checksum_tree (TYPE_CONTEXT (expr), ctx, ht);
07500 break;
07501 default:
07502 break;
07503 }
07504 }
07505
07506 #endif
07507
07508
07509
07510
07511
07512
07513
07514
07515
07516
07517
07518
07519
07520
07521
07522
07523
07524
07525
07526
07527
07528
07529
07530
07531
07532
07533
07534
07535
07536
07537
07538
07539
07540
07541
07542
07543
07544
07545
07546
07547
07548 static int
07549 multiple_of_p (type, top, bottom)
07550 tree type;
07551 tree top;
07552 tree bottom;
07553 {
07554 if (operand_equal_p (top, bottom, 0))
07555 return 1;
07556
07557 if (TREE_CODE (type) != INTEGER_TYPE)
07558 return 0;
07559
07560 switch (TREE_CODE (top))
07561 {
07562 case MULT_EXPR:
07563 return (multiple_of_p (type, TREE_OPERAND (top, 0), bottom)
07564 || multiple_of_p (type, TREE_OPERAND (top, 1), bottom));
07565
07566 case PLUS_EXPR:
07567 case MINUS_EXPR:
07568 return (multiple_of_p (type, TREE_OPERAND (top, 0), bottom)
07569 && multiple_of_p (type, TREE_OPERAND (top, 1), bottom));
07570
07571 case LSHIFT_EXPR:
07572 if (TREE_CODE (TREE_OPERAND (top, 1)) == INTEGER_CST)
07573 {
07574 tree op1, t1;
07575
07576 op1 = TREE_OPERAND (top, 1);
07577
07578
07579 if (TYPE_PRECISION (TREE_TYPE (size_one_node))
07580 > TREE_INT_CST_LOW (op1)
07581 && TREE_INT_CST_HIGH (op1) == 0
07582 && 0 != (t1 = convert (type,
07583 const_binop (LSHIFT_EXPR, size_one_node,
07584 op1, 0)))
07585 && ! TREE_OVERFLOW (t1))
07586 return multiple_of_p (type, t1, bottom);
07587 }
07588 return 0;
07589
07590 case NOP_EXPR:
07591
07592 if ((TREE_CODE (TREE_TYPE (TREE_OPERAND (top, 0))) != INTEGER_TYPE)
07593 || (TYPE_PRECISION (type)
07594 < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (top, 0)))))
07595 return 0;
07596
07597
07598
07599 case SAVE_EXPR:
07600 return multiple_of_p (type, TREE_OPERAND (top, 0), bottom);
07601
07602 case INTEGER_CST:
07603 if (TREE_CODE (bottom) != INTEGER_CST
07604 || (TREE_UNSIGNED (type)
07605 && (tree_int_cst_sgn (top) < 0
07606 || tree_int_cst_sgn (bottom) < 0)))
07607 return 0;
07608 return integer_zerop (const_binop (TRUNC_MOD_EXPR,
07609 top, bottom, 0));
07610
07611 default:
07612 return 0;
07613 }
07614 }
07615
07616
07617
07618 int
07619 tree_expr_nonnegative_p (t)
07620 tree t;
07621 {
07622 switch (TREE_CODE (t))
07623 {
07624 case ABS_EXPR:
07625 case FFS_EXPR:
07626 return 1;
07627 case INTEGER_CST:
07628 return tree_int_cst_sgn (t) >= 0;
07629 case TRUNC_DIV_EXPR:
07630 case CEIL_DIV_EXPR:
07631 case FLOOR_DIV_EXPR:
07632 case ROUND_DIV_EXPR:
07633 return tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
07634 && tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
07635 case TRUNC_MOD_EXPR:
07636 case CEIL_MOD_EXPR:
07637 case FLOOR_MOD_EXPR:
07638 case ROUND_MOD_EXPR:
07639 return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
07640 case COND_EXPR:
07641 return tree_expr_nonnegative_p (TREE_OPERAND (t, 1))
07642 && tree_expr_nonnegative_p (TREE_OPERAND (t, 2));
07643 case COMPOUND_EXPR:
07644 return tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
07645 case MIN_EXPR:
07646 return tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
07647 && tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
07648 case MAX_EXPR:
07649 return tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
07650 || tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
07651 case MODIFY_EXPR:
07652 return tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
07653 case BIND_EXPR:
07654 return tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
07655 case SAVE_EXPR:
07656 return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
07657 case NON_LVALUE_EXPR:
07658 return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
07659 case RTL_EXPR:
07660 return rtl_expr_nonnegative_p (RTL_EXPR_RTL (t));
07661
07662 default:
07663 if (truth_value_p (TREE_CODE (t)))
07664
07665 return 1;
07666 else
07667
07668 return 0;
07669 }
07670 }
07671
07672
07673
07674
07675 int
07676 rtl_expr_nonnegative_p (r)
07677 rtx r;
07678 {
07679 switch (GET_CODE (r))
07680 {
07681 case CONST_INT:
07682 return INTVAL (r) >= 0;
07683
07684 case CONST_DOUBLE:
07685 if (GET_MODE (r) == VOIDmode)
07686 return CONST_DOUBLE_HIGH (r) >= 0;
07687 return 0;
07688
07689 case CONST_VECTOR:
07690 {
07691 int units, i;
07692 rtx elt;
07693
07694 units = CONST_VECTOR_NUNITS (r);
07695
07696 for (i = 0; i < units; ++i)
07697 {
07698 elt = CONST_VECTOR_ELT (r, i);
07699 if (!rtl_expr_nonnegative_p (elt))
07700 return 0;
07701 }
07702
07703 return 1;
07704 }
07705
07706 case SYMBOL_REF:
07707 case LABEL_REF:
07708
07709 return 1;
07710
07711 default:
07712 return 0;
07713 }
07714 }
07715
07716 #include "gt-fold-const.h"