|
|
1.1 ! root 1: /*@@ Fix lossage on folding division of big integers. */ ! 2: ! 3: /*@@ This file should be rewritten to use an arbitary precision ! 4: @@ representation for "struct tree_int_cst" and "struct tree_real_cst". ! 5: @@ Perhaps the routines could also be used for bc/dc, and made a lib. ! 6: @@ The routines that translate from the ap rep should ! 7: @@ warn if precision et. al. is lost. ! 8: @@ This would also make life easier when this technology is used ! 9: @@ for cross-compilers. */ ! 10: ! 11: /* Fold a constant sub-tree into a single node for C-compiler ! 12: Copyright (C) 1987, 1988 Free Software Foundation, Inc. ! 13: ! 14: This file is part of GNU CC. ! 15: ! 16: GNU CC is distributed in the hope that it will be useful, ! 17: but WITHOUT ANY WARRANTY. No author or distributor ! 18: accepts responsibility to anyone for the consequences of using it ! 19: or for whether it serves any particular purpose or works at all, ! 20: unless he says so in writing. Refer to the GNU CC General Public ! 21: License for full details. ! 22: ! 23: Everyone is granted permission to copy, modify and redistribute ! 24: GNU CC, but only under the conditions described in the ! 25: GNU CC General Public License. A copy of this license is ! 26: supposed to have been given to you along with GNU CC so you ! 27: can know your rights and responsibilities. It should be in a ! 28: file named COPYING. Among other things, the copyright notice ! 29: and this notice must be preserved on all copies. */ ! 30: ! 31: ! 32: /* There are only two entry points in this file: ! 33: fold and combine. ! 34: ! 35: fold takes a tree as argument and returns a simplified tree. ! 36: ! 37: combine takes a tree code for an arithmetic operation ! 38: and two operands that are trees for constant values ! 39: and returns the result of the specified operation on those values, ! 40: also as a tree. */ ! 41: ! 42: #include <stdio.h> ! 43: #include "config.h" ! 44: #include "tree.h" ! 45: ! 46: static void lshift_double (); ! 47: static void rshift_double (); ! 48: static void lrotate_double (); ! 49: static void rrotate_double (); ! 50: ! 51: /* To do constant folding on INTEGER_CST nodes requires 64-bit arithmetic. ! 52: We do that by representing the 64-bit integer as 8 shorts, ! 53: with only 8 bits stored in each short, as a positive number. */ ! 54: ! 55: /* Unpack a 64-bit integer into 8 shorts. ! 56: LOW and HI are the integer, as two `int' pieces. ! 57: SHORTS points to the array of shorts. */ ! 58: ! 59: static void ! 60: encode (shorts, low, hi) ! 61: short *shorts; ! 62: int low, hi; ! 63: { ! 64: shorts[0] = low & 0xff; ! 65: shorts[1] = (low >> 8) & 0xff; ! 66: shorts[2] = (low >> 16) & 0xff; ! 67: shorts[3] = (low >> 24) & 0xff; ! 68: shorts[4] = hi & 0xff; ! 69: shorts[5] = (hi >> 8) & 0xff; ! 70: shorts[6] = (hi >> 16) & 0xff; ! 71: shorts[7] = (hi >> 24) & 0xff; ! 72: } ! 73: ! 74: /* Pack an array of 8 shorts into a 64-bit integer. ! 75: SHORTS points to the array of shorts. ! 76: The integer is stored into *LOW and *HI as two `int' pieces. */ ! 77: ! 78: static void ! 79: decode (shorts, low, hi) ! 80: short *shorts; ! 81: int *low, *hi; ! 82: { ! 83: *low = (shorts[3] << 24) | (shorts[2] << 16) | (shorts[1] << 8) | shorts[0]; ! 84: *hi = (shorts[7] << 24) | (shorts[6] << 16) | (shorts[5] << 8) | shorts[4]; ! 85: } ! 86: ! 87: /* Make the integer constant T valid for its type ! 88: by setting to 0 or 1 all the bits in the constant ! 89: that don't belong in the type. */ ! 90: ! 91: static void ! 92: force_fit_type (t) ! 93: tree t; ! 94: { ! 95: register int prec = TYPE_PRECISION (TREE_TYPE (t)); ! 96: ! 97: if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE) ! 98: prec = BITS_PER_WORD; ! 99: ! 100: /* First clear all bits that are beyond the type's precision. */ ! 101: ! 102: if (prec > HOST_BITS_PER_INT) ! 103: { ! 104: TREE_INT_CST_HIGH (t) ! 105: &= ~((-1) << (prec - HOST_BITS_PER_INT)); ! 106: } ! 107: else ! 108: { ! 109: TREE_INT_CST_HIGH (t) = 0; ! 110: if (prec < HOST_BITS_PER_INT) ! 111: TREE_INT_CST_LOW (t) ! 112: &= ~((-1) << prec); ! 113: } ! 114: ! 115: /* If it's a signed type and value's sign bit is set, extend the sign. */ ! 116: ! 117: if (! TREE_UNSIGNED (TREE_TYPE (t)) ! 118: && (prec > HOST_BITS_PER_INT ! 119: ? TREE_INT_CST_HIGH (t) & (1 << (prec - HOST_BITS_PER_INT - 1)) ! 120: : TREE_INT_CST_LOW (t) & (1 << (prec - 1)))) ! 121: { ! 122: /* Value is negative: ! 123: set to 1 all the bits that are outside this type's precision. */ ! 124: if (prec > HOST_BITS_PER_INT) ! 125: { ! 126: TREE_INT_CST_HIGH (t) ! 127: |= ((-1) << (prec - HOST_BITS_PER_INT)); ! 128: } ! 129: else ! 130: { ! 131: TREE_INT_CST_HIGH (t) = -1; ! 132: if (prec < HOST_BITS_PER_INT) ! 133: TREE_INT_CST_LOW (t) ! 134: |= ((-1) << prec); ! 135: } ! 136: } ! 137: } ! 138: ! 139: /* Add two 64-bit integers with 64-bit result. ! 140: Each argument is given as two `int' pieces. ! 141: One argument is L1 and H1; the other, L2 and H2. ! 142: The value is stored as two `int' pieces in *LV and *HV. ! 143: We use the 8-shorts representation internally. */ ! 144: ! 145: static void ! 146: add_double (l1, h1, l2, h2, lv, hv) ! 147: int l1, h1, l2, h2; ! 148: int *lv, *hv; ! 149: { ! 150: short arg1[8]; ! 151: short arg2[8]; ! 152: register int carry = 0; ! 153: register int i; ! 154: ! 155: encode (arg1, l1, h1); ! 156: encode (arg2, l2, h2); ! 157: ! 158: for (i = 0; i < 8; i++) ! 159: { ! 160: carry += arg1[i] + arg2[i]; ! 161: arg1[i] = carry & 0xff; ! 162: carry >>= 8; ! 163: } ! 164: ! 165: decode (arg1, lv, hv); ! 166: } ! 167: ! 168: /* Negate a 64-bit integers with 64-bit result. ! 169: The argument is given as two `int' pieces in L1 and H1. ! 170: The value is stored as two `int' pieces in *LV and *HV. ! 171: We use the 8-shorts representation internally. */ ! 172: ! 173: static void ! 174: neg_double (l1, h1, lv, hv) ! 175: int l1, h1; ! 176: int *lv, *hv; ! 177: { ! 178: if (l1 == 0) ! 179: { ! 180: *lv = 0; ! 181: *hv = - h1; ! 182: } ! 183: else ! 184: { ! 185: *lv = - l1; ! 186: *hv = ~ h1; ! 187: } ! 188: } ! 189: ! 190: /* Multiply two 64-bit integers with 64-bit result. ! 191: Each argument is given as two `int' pieces. ! 192: One argument is L1 and H1; the other, L2 and H2. ! 193: The value is stored as two `int' pieces in *LV and *HV. ! 194: We use the 8-shorts representation internally. */ ! 195: ! 196: static void ! 197: mul_double (l1, h1, l2, h2, lv, hv) ! 198: int l1, h1, l2, h2; ! 199: int *lv, *hv; ! 200: { ! 201: short arg1[8]; ! 202: short arg2[8]; ! 203: short prod[16]; ! 204: register int carry = 0; ! 205: register int i, j, k; ! 206: ! 207: encode (arg1, l1, h1); ! 208: encode (arg2, l2, h2); ! 209: ! 210: bzero (prod, sizeof prod); ! 211: ! 212: for (i = 0; i < 8; i++) ! 213: for (j = 0; j < 8; j++) ! 214: { ! 215: k = i + j; ! 216: carry = arg1[i] * arg2[j]; ! 217: while (carry) ! 218: { ! 219: carry += prod[k]; ! 220: prod[k] = carry & 0xff; ! 221: carry >>= 8; ! 222: k++; ! 223: } ! 224: } ! 225: ! 226: decode (prod, lv, hv); /* @@decode ignores prod[8] -> prod[15] */ ! 227: } ! 228: ! 229: /* Shift the 64-bit integer in L1, H1 left by COUNT places ! 230: keeping only PREC bits of result. ! 231: Shift right if COUNT is negative. ! 232: ARITH nonzero specifies arithmetic shifting; otherwise use logical shift. ! 233: Store the value as two `int' pieces in *LV and *HV. */ ! 234: ! 235: static void ! 236: lshift_double (l1, h1, count, prec, lv, hv, arith) ! 237: int l1, h1, count, prec; ! 238: int *lv, *hv; ! 239: int arith; ! 240: { ! 241: short arg1[8]; ! 242: register int i; ! 243: register int carry; ! 244: ! 245: if (count < 0) ! 246: { ! 247: rshift_double (l1, h1, - count, prec, lv, hv, arith); ! 248: return; ! 249: } ! 250: ! 251: encode (arg1, l1, h1); ! 252: if (prec < HOST_BITS_PER_INT) ! 253: count &= (1 << prec) - 1; ! 254: ! 255: while (count > 0) ! 256: { ! 257: carry = 0; ! 258: for (i = 0; i < 8; i++) ! 259: { ! 260: carry += arg1[i] << 1; ! 261: arg1[i] = carry & 0xff; ! 262: carry >>= 8; ! 263: } ! 264: count--; ! 265: } ! 266: ! 267: decode (arg1, lv, hv); ! 268: } ! 269: ! 270: /* Shift the 64-bit integer in L1, H1 right by COUNT places ! 271: keeping only PREC bits of result. COUNT must be positive. ! 272: ARITH nonzero specifies arithmetic shifting; otherwise use logical shift. ! 273: Store the value as two `int' pieces in *LV and *HV. */ ! 274: ! 275: static void ! 276: rshift_double (l1, h1, count, prec, lv, hv, arith) ! 277: int l1, h1, count, prec; ! 278: int *lv, *hv; ! 279: int arith; ! 280: { ! 281: short arg1[8]; ! 282: register int i; ! 283: register int carry; ! 284: ! 285: encode (arg1, l1, h1); ! 286: if (prec < HOST_BITS_PER_INT) ! 287: count &= (1 << prec) - 1; ! 288: ! 289: carry = arith && arg1[7] >> 7; ! 290: while (count > 0) ! 291: { ! 292: for (i = 7; i >= 0; i--) ! 293: { ! 294: carry <<= 8; ! 295: carry += arg1[i]; ! 296: arg1[i] = (carry >> 1) & 0xff; ! 297: } ! 298: count--; ! 299: } ! 300: ! 301: decode (arg1, lv, hv); ! 302: } ! 303: ! 304: /* Rotate the 64-bit integer in L1, H1 left by COUNT places ! 305: keeping only PREC bits of result. ! 306: Rotate right if COUNT is negative. ! 307: Store the value as two `int' pieces in *LV and *HV. */ ! 308: ! 309: static void ! 310: lrotate_double (l1, h1, count, prec, lv, hv) ! 311: int l1, h1, count, prec; ! 312: int *lv, *hv; ! 313: { ! 314: short arg1[8]; ! 315: register int i; ! 316: register int carry; ! 317: ! 318: if (count < 0) ! 319: { ! 320: rrotate_double (l1, h1, - count, prec, lv, hv); ! 321: return; ! 322: } ! 323: ! 324: encode (arg1, l1, h1); ! 325: if (prec < HOST_BITS_PER_INT) ! 326: count &= (1 << prec) - 1; ! 327: ! 328: carry = arg1[7] >> 7; ! 329: while (count > 0) ! 330: { ! 331: for (i = 0; i < 8; i++) ! 332: { ! 333: carry += arg1[i] << 1; ! 334: arg1[i] = carry & 0xff; ! 335: carry >>= 8; ! 336: } ! 337: count--; ! 338: } ! 339: ! 340: decode (arg1, lv, hv); ! 341: } ! 342: ! 343: /* Rotate the 64-bit integer in L1, H1 left by COUNT places ! 344: keeping only PREC bits of result. COUNT must be positive. ! 345: Store the value as two `int' pieces in *LV and *HV. */ ! 346: ! 347: static void ! 348: rrotate_double (l1, h1, count, prec, lv, hv) ! 349: int l1, h1, count, prec; ! 350: int *lv, *hv; ! 351: { ! 352: short arg1[8]; ! 353: register int i; ! 354: register int carry; ! 355: ! 356: encode (arg1, l1, h1); ! 357: if (prec < HOST_BITS_PER_INT) ! 358: count &= (1 << prec) - 1; ! 359: ! 360: carry = arg1[0] & 1; ! 361: while (count > 0) ! 362: { ! 363: for (i = 7; i >= 0; i--) ! 364: { ! 365: carry <<= 8; ! 366: carry += arg1[i]; ! 367: arg1[i] = (carry >> 1) & 0xff; ! 368: } ! 369: count--; ! 370: } ! 371: ! 372: decode (arg1, lv, hv); ! 373: } ! 374: ! 375: /* Divide 64 bit integer LNUM, HNUM by 64 bit integer LDEN, HDEN ! 376: for a quotient (stored in *LQUO, *HQUO) and remainder (in *LREM, *HREM). ! 377: CODE is a tree code for a kind of division, one of ! 378: TRUNC_DIV_EXPR, FLOOR_DIV_EXPR, CEIL_DIV_EXPR and ROUND_DIV_EXPR. ! 379: It controls how the quotient is rounded to a integer. ! 380: UNS nonzero says do unsigned division. */ ! 381: ! 382: static void ! 383: div_and_round_double (code, uns, ! 384: lnum_orig, hnum_orig, lden_orig, hden_orig, ! 385: lquo, hquo, lrem, hrem) ! 386: enum tree_code code; ! 387: int uns; ! 388: int lnum_orig, hnum_orig; /* num == numerator == dividend */ ! 389: int lden_orig, hden_orig; /* den == denominator == divisor */ ! 390: int *lquo, *hquo, *lrem, *hrem; ! 391: { ! 392: int quo_neg = 0; ! 393: short num[9], den[8], quo[8]; /* extra element for scaling. */ ! 394: register int i, j, work; ! 395: register int carry = 0; ! 396: int lnum = lnum_orig, hnum = hnum_orig; ! 397: int lden = lden_orig, hden = hden_orig; ! 398: ! 399: if ((hden == 0) && (lden == 0)) { ! 400: *hquo = *lquo = *hrem = *lrem = 0; ! 401: error ! 402: ("divide by 0 in constant folding - quotient and remainder set to 0."); ! 403: return; ! 404: } ! 405: ! 406: /* calculate quotient sign and convert operands to unsigned. */ ! 407: if (!uns) ! 408: { ! 409: if (hden < 0) ! 410: { ! 411: quo_neg = ~ quo_neg; ! 412: neg_double (lden, hden, &lden, &hden); ! 413: } ! 414: if (hnum < 0) ! 415: { ! 416: quo_neg = ~ quo_neg; ! 417: neg_double (lnum, hnum, &lnum, &hnum); ! 418: } ! 419: } ! 420: ! 421: if (hnum == 0 && hden == 0) ! 422: { /* single precision */ ! 423: *hquo = *hrem = 0; ! 424: *lquo = (unsigned) lnum / lden; /* rounds toward zero since positive args */ ! 425: goto finish_up; ! 426: } ! 427: ! 428: if (hnum == 0) ! 429: { /* trivial case: dividend < divisor */ ! 430: /* hden != 0 already checked. */ ! 431: *hquo = *lquo = 0; ! 432: *hrem = hnum; ! 433: *lrem = lnum; ! 434: goto finish_up; ! 435: } ! 436: ! 437: bzero (quo, sizeof quo); ! 438: ! 439: bzero (num, sizeof num); /* to zero 9th element */ ! 440: bzero (den, sizeof den); ! 441: ! 442: encode (num, lnum, hnum); ! 443: encode (den, lden, hden); ! 444: ! 445: if (hden == 0) ! 446: { /* simpler algorithm */ ! 447: /* hnum != 0 already checked. */ ! 448: for (i = 7; i >= 0; i--) ! 449: { ! 450: work = num[i] + (carry << 8); ! 451: quo[i] = work / lden; ! 452: carry = work % lden; ! 453: } ! 454: } ! 455: else { /* full double precision, ! 456: with thanks to Don Knuth's ! 457: "Semi-Numericial Algorithms". */ ! 458: #define BASE 256 ! 459: int quo_est, scale, num_hi_sig, den_hi_sig, quo_hi_sig; ! 460: ! 461: /* Find the highest non-zero divisor digit. */ ! 462: for (i = 7; ; i--) ! 463: if (den[i] != 0) { ! 464: den_hi_sig = i; ! 465: break; ! 466: } ! 467: for (i = 7; ; i--) ! 468: if (num[i] != 0) { ! 469: num_hi_sig = i; ! 470: break; ! 471: } ! 472: quo_hi_sig = num_hi_sig - den_hi_sig + 1; ! 473: ! 474: /* Insure that the first digit of the divisor is at least BASE/2. ! 475: This is required by the quotient digit estimation algorithm. */ ! 476: ! 477: scale = BASE / (den[den_hi_sig] + 1); ! 478: if (scale > 1) { /* scale divisor and dividend */ ! 479: carry = 0; ! 480: for (i = 0; i <= 8; i++) { ! 481: work = (num[i] * scale) + carry; ! 482: num[i] = work & 0xff; ! 483: carry = work >> 8; ! 484: if (num[i] != 0) num_hi_sig = i; ! 485: } ! 486: carry = 0; ! 487: for (i = 0; i <= 7; i++) { ! 488: work = (den[i] * scale) + carry; ! 489: den[i] = work & 0xff; ! 490: carry = work >> 8; ! 491: if (den[i] != 0) den_hi_sig = i; ! 492: } ! 493: } ! 494: ! 495: /* Main loop */ ! 496: for (i = quo_hi_sig; i > 0; i--) { ! 497: /* quess the next quotient digit, quo_est, by dividing the first ! 498: two remaining dividend digits by the high order quotient digit. ! 499: quo_est is never low and is at most 2 high. */ ! 500: ! 501: int num_hi; /* index of highest remaining dividend digit */ ! 502: ! 503: num_hi = i + den_hi_sig; ! 504: ! 505: work = (num[num_hi] * BASE) + (num_hi ? 0 : num[num_hi - 1]); ! 506: if (num[num_hi] != den[den_hi_sig]) { ! 507: quo_est = work / den[den_hi_sig]; ! 508: } ! 509: else { ! 510: quo_est = BASE - 1; ! 511: } ! 512: ! 513: /* refine quo_est so it's usually correct, and at most one high. */ ! 514: while ((den[den_hi_sig - 1] * quo_est) ! 515: > (((work - (quo_est * den[den_hi_sig])) * BASE) ! 516: + ((num_hi - 1) ? 0 : num[num_hi - 2]))) { ! 517: quo_est--; ! 518: } ! 519: ! 520: /* try quo_est as the quotient digit, by multiplying the ! 521: divisor by quo_est and subtracting from the remaining dividend. */ ! 522: ! 523: carry = 0; ! 524: ! 525: for (j = 0; j <= den_hi_sig; j++) { ! 526: int digit; ! 527: ! 528: work = num[i + j] - (quo_est * den[j]) + carry; ! 529: digit = work & 0xff; ! 530: carry = work >> 8; ! 531: if (digit < 0) { ! 532: digit += BASE; ! 533: carry--; ! 534: } ! 535: num[i + j] = digit; ! 536: } ! 537: ! 538: /* if quo_est was high by one, then num[i] went negative and ! 539: we need to correct things. */ ! 540: ! 541: if (num[num_hi] < 0) { ! 542: quo_est--; ! 543: carry = 0; /* add divisor back in */ ! 544: for (j = 0; j <= den_hi_sig; j++) { ! 545: work = num[i + j] + den[j] + carry; ! 546: if (work > BASE) { ! 547: work -= BASE; ! 548: carry = 1; ! 549: } ! 550: else { ! 551: carry = 0; ! 552: } ! 553: num[i + j] = work; ! 554: } ! 555: num [num_hi] += carry; ! 556: } ! 557: ! 558: /* store the quotient digit. */ ! 559: quo[i - 1] = quo_est; ! 560: } ! 561: } ! 562: ! 563: decode (quo, lquo, hquo); ! 564: ! 565: finish_up: ! 566: /* if result is negative, make it so. */ ! 567: if (quo_neg) ! 568: neg_double (*lquo, *hquo, lquo, hquo); ! 569: ! 570: /* compute trial remainder: rem = num - (quo * den) */ ! 571: mul_double (*lquo, *hquo, lden_orig, hden_orig, lrem, hrem); ! 572: neg_double (*lrem, *hrem, lrem, hrem); ! 573: add_double (lnum_orig, hnum_orig, *lrem, *hrem, lrem, hrem); ! 574: ! 575: switch (code) ! 576: { ! 577: case TRUNC_DIV_EXPR: ! 578: case TRUNC_MOD_EXPR: /* round toward zero */ ! 579: return; ! 580: ! 581: case FLOOR_DIV_EXPR: ! 582: case FLOOR_MOD_EXPR: /* round toward negative infinity */ ! 583: if (quo_neg && (*lrem != 0 || *hrem != 0)) /* ratio < 0 && rem != 0 */ ! 584: { ! 585: /* quo = quo - 1; */ ! 586: add_double (*lquo, *hquo, -1, -1, lquo, hquo); ! 587: } ! 588: else return; ! 589: break; ! 590: ! 591: case CEIL_DIV_EXPR: ! 592: case CEIL_MOD_EXPR: /* round toward positive infinity */ ! 593: if (!quo_neg && (*lrem != 0 || *hrem != 0)) /* ratio > 0 && rem != 0 */ ! 594: { ! 595: add_double (*lquo, *hquo, 1, 0, lquo, hquo); ! 596: } ! 597: else return; ! 598: break; ! 599: ! 600: case ROUND_DIV_EXPR: ! 601: case ROUND_MOD_EXPR: /* round to closest integer */ ! 602: { ! 603: int labs_rem = *lrem, habs_rem = *hrem; ! 604: int labs_den = lden, habs_den = hden, ltwice, htwice; ! 605: ! 606: /* get absolute values */ ! 607: if (*hrem < 0) neg_double(*lrem, *hrem, &labs_rem, &habs_rem); ! 608: if (hden < 0) neg_double(lden, hden, &labs_den, &habs_den); ! 609: ! 610: /* if (2 * abs (lrem) >= abs (lden)) */ ! 611: mul_double(2, 0, labs_rem, habs_rem, <wice, &htwice); ! 612: if (((unsigned) habs_den < (unsigned) htwice) ! 613: || (((unsigned) habs_den == (unsigned) htwice) ! 614: && ((unsigned) labs_den < (unsigned) ltwice))) ! 615: { ! 616: if (*hquo < 0) ! 617: /* quo = quo - 1; */ ! 618: add_double (*lquo, *hquo, -1, -1, lquo, hquo); ! 619: else ! 620: /* quo = quo + 1; */ ! 621: add_double (*lquo, *hquo, 1, 0, lquo, hquo); ! 622: } ! 623: else return; ! 624: } ! 625: break; ! 626: ! 627: default: ! 628: abort (); ! 629: } ! 630: ! 631: /* compute true remainder: rem = num - (quo * den) */ ! 632: mul_double (*lquo, *hquo, lden_orig, hden_orig, lrem, hrem); ! 633: neg_double (*lrem, *hrem, lrem, hrem); ! 634: add_double (lnum_orig, hnum_orig, *lrem, *hrem, lrem, hrem); ! 635: } ! 636: ! 637: /* Split a tree IN into a constant and a variable part ! 638: that could be combined with CODE to make IN. ! 639: CODE must be a commutative arithmetic operation. ! 640: Store the constant part into *CONP and the variable in &VARP. ! 641: Return 1 if this was done; zero means the tree IN did not decompose ! 642: this way. ! 643: ! 644: If CODE is PLUS_EXPR we also split trees that use MINUS_EXPR. ! 645: Therefore, we must tell the caller whether the variable part ! 646: was subtracted. We do this by storing 1 or -1 into *VARSIGNP. ! 647: The value stored is the coefficient for the variable term. ! 648: The constant term we return should always be added; ! 649: we negate it if necessary. */ ! 650: ! 651: static int ! 652: split_tree (in, code, varp, conp, varsignp) ! 653: tree in; ! 654: enum tree_code code; ! 655: tree *varp, *conp; ! 656: int *varsignp; ! 657: { ! 658: register tree outtype = TREE_TYPE (in); ! 659: *varp = 0; ! 660: *conp = 0; ! 661: ! 662: /* Strip any conversions that don't change the machine mode. */ ! 663: while ((TREE_CODE (in) == NOP_EXPR ! 664: || TREE_CODE (in) == CONVERT_EXPR) ! 665: && (TYPE_MODE (TREE_TYPE (in)) ! 666: == TYPE_MODE (TREE_TYPE (TREE_OPERAND (in, 0))))) ! 667: in = TREE_OPERAND (in, 0); ! 668: ! 669: if (TREE_CODE (in) == code ! 670: || (TREE_CODE (TREE_TYPE (in)) != REAL_TYPE ! 671: /* We can associate addition and subtraction together ! 672: (even though the C standard doesn't say so) ! 673: for integers because the value is not affected. ! 674: For reals, the value might be affected, so we can't. */ ! 675: && ! 676: ((code == PLUS_EXPR && TREE_CODE (in) == MINUS_EXPR) ! 677: || (code == MINUS_EXPR && TREE_CODE (in) == PLUS_EXPR)))) ! 678: { ! 679: enum tree_code code = TREE_CODE (TREE_OPERAND (in, 0)); ! 680: if (code == INTEGER_CST || code == REAL_CST) ! 681: { ! 682: *conp = TREE_OPERAND (in, 0); ! 683: *varp = TREE_OPERAND (in, 1); ! 684: if (TREE_TYPE (*varp) != outtype) ! 685: *varp = convert (outtype, *varp); ! 686: *varsignp = (TREE_CODE (in) == MINUS_EXPR) ? -1 : 1; ! 687: return 1; ! 688: } ! 689: if (TREE_LITERAL (TREE_OPERAND (in, 1))) ! 690: { ! 691: *conp = TREE_OPERAND (in, 1); ! 692: *varp = TREE_OPERAND (in, 0); ! 693: *varsignp = 1; ! 694: if (TREE_TYPE (*varp) != outtype) ! 695: *varp = convert (outtype, *varp); ! 696: if (TREE_CODE (in) == MINUS_EXPR) ! 697: { ! 698: /* If operation is subtraction and constant is second, ! 699: must negate it to get an additive constant. ! 700: And this cannot be done unless it is a manifest constant. ! 701: It could also be the address of a static variable. ! 702: We cannot negate that, so give up. */ ! 703: if (TREE_CODE (*conp) == INTEGER_CST ! 704: || TREE_CODE (*conp) == REAL_CST) ! 705: *conp = combine (MINUS_EXPR, integer_zero_node, *conp); ! 706: else ! 707: return 0; ! 708: } ! 709: return 1; ! 710: } ! 711: if (TREE_LITERAL (TREE_OPERAND (in, 0))) ! 712: { ! 713: *conp = TREE_OPERAND (in, 0); ! 714: *varp = TREE_OPERAND (in, 1); ! 715: if (TREE_TYPE (*varp) != outtype) ! 716: *varp = convert (outtype, *varp); ! 717: *varsignp = (TREE_CODE (in) == MINUS_EXPR) ? -1 : 1; ! 718: return 1; ! 719: } ! 720: } ! 721: return 0; ! 722: } ! 723: ! 724: /* Combine two constants NUM and ARG2 under operation CODE ! 725: to produce a new constant. ! 726: We assume ARG1 and ARG2 have the same data type, ! 727: or at least are the same kind of constant and the same machine mode. */ ! 728: ! 729: tree ! 730: combine (code, arg1, arg2) ! 731: enum tree_code code; ! 732: register tree arg1, arg2; ! 733: { ! 734: if (TREE_CODE (arg1) == INTEGER_CST) ! 735: { ! 736: register int int1l = TREE_INT_CST_LOW (arg1); ! 737: register int int1h = TREE_INT_CST_HIGH (arg1); ! 738: int int2l = TREE_INT_CST_LOW (arg2); ! 739: int int2h = TREE_INT_CST_HIGH (arg2); ! 740: int low, hi; ! 741: int garbagel, garbageh; ! 742: register tree t; ! 743: int uns = TREE_UNSIGNED (TREE_TYPE (arg1)); ! 744: ! 745: switch (code) ! 746: { ! 747: case BIT_IOR_EXPR: ! 748: t = build_int_2 (int1l | int2l, int1h | int2h); ! 749: break; ! 750: ! 751: case BIT_XOR_EXPR: ! 752: t = build_int_2 (int1l ^ int2l, int1h ^ int2h); ! 753: break; ! 754: ! 755: case BIT_AND_EXPR: ! 756: t = build_int_2 (int1l & int2l, int1h & int2h); ! 757: break; ! 758: ! 759: case BIT_ANDTC_EXPR: ! 760: t = build_int_2 (int1l & ~int2l, int1h & ~int2h); ! 761: break; ! 762: ! 763: case RSHIFT_EXPR: ! 764: int2l = - int2l; ! 765: case LSHIFT_EXPR: ! 766: lshift_double (int1l, int1h, int2l, ! 767: TYPE_PRECISION (TREE_TYPE (arg1)), ! 768: &low, &hi, ! 769: !uns); ! 770: t = build_int_2 (low, hi); ! 771: break; ! 772: ! 773: case RROTATE_EXPR: ! 774: int2l = - int2l; ! 775: case LROTATE_EXPR: ! 776: lrotate_double (int1l, int1h, int2l, ! 777: TYPE_PRECISION (TREE_TYPE (arg1)), ! 778: &low, &hi); ! 779: t = build_int_2 (low, hi); ! 780: break; ! 781: ! 782: case PLUS_EXPR: ! 783: add_double (int1l, int1h, int2l, int2h, &low, &hi); ! 784: t = build_int_2 (low, hi); ! 785: break; ! 786: ! 787: case MINUS_EXPR: ! 788: neg_double (int2l, int2h, &int2l, &int2h); ! 789: add_double (int1l, int1h, int2l, int2h, &low, &hi); ! 790: t = build_int_2 (low, hi); ! 791: break; ! 792: ! 793: case MULT_EXPR: ! 794: mul_double (int1l, int1h, int2l, int2h, &low, &hi); ! 795: t = build_int_2 (low, hi); ! 796: break; ! 797: ! 798: case TRUNC_DIV_EXPR: case ROUND_DIV_EXPR: ! 799: case FLOOR_DIV_EXPR: case CEIL_DIV_EXPR: ! 800: div_and_round_double (code, uns, int1l, int1h, int2l, int2h, ! 801: &low, &hi, &garbagel, &garbageh); ! 802: t = build_int_2 (low, hi); ! 803: break; ! 804: ! 805: case TRUNC_MOD_EXPR: case ROUND_MOD_EXPR: ! 806: case FLOOR_MOD_EXPR: case CEIL_MOD_EXPR: ! 807: div_and_round_double (code, uns, int1l, int1h, int2l, int2h, ! 808: &garbagel, &garbageh, &low, &hi); ! 809: t = build_int_2 (low, hi); ! 810: break; ! 811: ! 812: case MIN_EXPR: ! 813: case MAX_EXPR: ! 814: if (uns) ! 815: { ! 816: low = (((unsigned) int1h < (unsigned) int2h) ! 817: || (((unsigned) int1h == (unsigned) int2h) ! 818: && ((unsigned) int1l < (unsigned) int2l))); ! 819: } ! 820: else ! 821: { ! 822: low = ((int1h < int2h) ! 823: || ((int1h == int2h) ! 824: && ((unsigned) int1l < (unsigned) int2l))); ! 825: } ! 826: if (low == (code == MIN_EXPR)) ! 827: t = build_int_2 (int1l, int1h); ! 828: else ! 829: t = build_int_2 (int2l, int2h); ! 830: break; ! 831: ! 832: default: ! 833: abort (); ! 834: } ! 835: TREE_TYPE (t) = TREE_TYPE (arg1); ! 836: force_fit_type (t); ! 837: return t; ! 838: } ! 839: if (TREE_CODE (arg1) == REAL_CST) ! 840: { ! 841: register double d1 = TREE_REAL_CST (arg1); ! 842: register double d2 = TREE_REAL_CST (arg2); ! 843: register tree t; ! 844: ! 845: switch (code) ! 846: { ! 847: case PLUS_EXPR: ! 848: t = build_real (d1 + d2); ! 849: break; ! 850: ! 851: case MINUS_EXPR: ! 852: t = build_real (d1 - d2); ! 853: break; ! 854: ! 855: case MULT_EXPR: ! 856: t = build_real (d1 * d2); ! 857: break; ! 858: ! 859: case RDIV_EXPR: ! 860: if (d2 == 0) ! 861: return 0; ! 862: ! 863: t = build_real (d1 / d2); ! 864: break; ! 865: ! 866: case MIN_EXPR: ! 867: if (d1 < d2) ! 868: t = build_real (d1); ! 869: else ! 870: t = build_real (d2); ! 871: break; ! 872: ! 873: case MAX_EXPR: ! 874: if (d1 > d2) ! 875: t = build_real (d1); ! 876: else ! 877: t = build_real (d2); ! 878: break; ! 879: ! 880: default: ! 881: abort (); ! 882: } ! 883: TREE_TYPE (t) = TREE_TYPE (arg1); ! 884: return t; ! 885: } ! 886: if (TREE_CODE (arg1) == COMPLEX_CST) ! 887: { ! 888: register tree r1 = TREE_REALPART (arg1); ! 889: register tree i1 = TREE_IMAGPART (arg1); ! 890: register tree r2 = TREE_REALPART (arg2); ! 891: register tree i2 = TREE_IMAGPART (arg2); ! 892: register tree t; ! 893: ! 894: switch (code) ! 895: { ! 896: case PLUS_EXPR: ! 897: t = build_complex (combine (PLUS_EXPR, r1, r2), ! 898: combine (PLUS_EXPR, i1, i2)); ! 899: break; ! 900: ! 901: case MINUS_EXPR: ! 902: t = build_complex (combine (MINUS_EXPR, r1, r2), ! 903: combine (MINUS_EXPR, i1, i2)); ! 904: break; ! 905: ! 906: case MULT_EXPR: ! 907: t = build_complex (combine (MINUS_EXPR, ! 908: combine (MULT_EXPR, r1, r2), ! 909: combine (MULT_EXPR, i1, i2)), ! 910: combine (PLUS_EXPR, ! 911: combine (MULT_EXPR, r1, i2), ! 912: combine (MULT_EXPR, i1, r2))); ! 913: break; ! 914: ! 915: case RDIV_EXPR: ! 916: { ! 917: register tree magsquared ! 918: = combine (PLUS_EXPR, ! 919: combine (MULT_EXPR, r2, r2), ! 920: combine (MULT_EXPR, i2, i2)); ! 921: t = build_complex (combine (RDIV_EXPR, ! 922: combine (PLUS_EXPR, ! 923: combine (MULT_EXPR, r1, r2), ! 924: combine (MULT_EXPR, i1, i2)), ! 925: magsquared), ! 926: combine (RDIV_EXPR, ! 927: combine (MINUS_EXPR, ! 928: combine (MULT_EXPR, i1, r2), ! 929: combine (MULT_EXPR, r1, i2)), ! 930: magsquared)); ! 931: } ! 932: break; ! 933: ! 934: default: ! 935: abort (); ! 936: } ! 937: TREE_TYPE (t) = TREE_TYPE (arg1); ! 938: return t; ! 939: } ! 940: return 0; ! 941: } ! 942: ! 943: /* Given T, a tree representing type conversion of a constant, ! 944: return a constant tree representing the result of conversion. */ ! 945: ! 946: static tree ! 947: fold_convert (t) ! 948: register tree t; ! 949: { ! 950: register tree arg1 = TREE_OPERAND (t, 0); ! 951: register tree type = TREE_TYPE (t); ! 952: ! 953: if (TREE_CODE (type) == POINTER_TYPE ! 954: || TREE_CODE (type) == INTEGER_TYPE ! 955: || TREE_CODE (type) == ENUMERAL_TYPE) ! 956: { ! 957: if (TREE_CODE (arg1) == INTEGER_CST) ! 958: { ! 959: /* Given an integer constant, make new constant with new type, ! 960: appropriately sign-extended or truncated. */ ! 961: register int inprec; ! 962: register int outprec; ! 963: ! 964: if (TREE_CODE (TREE_TYPE (arg1)) == POINTER_TYPE) ! 965: inprec = BITS_PER_WORD; ! 966: else ! 967: inprec = TYPE_PRECISION (TREE_TYPE (arg1)); ! 968: if (TREE_CODE (type) == POINTER_TYPE) ! 969: outprec = BITS_PER_WORD; ! 970: else ! 971: outprec = TYPE_PRECISION (type); ! 972: ! 973: t = build_int_2 (TREE_INT_CST_LOW (arg1), ! 974: TREE_INT_CST_HIGH (arg1)); ! 975: TREE_TYPE (t) = type; ! 976: force_fit_type (t); ! 977: } ! 978: else if (TREE_CODE (arg1) == REAL_CST) ! 979: t = build_int_2 ((int) TREE_REAL_CST (arg1), ! 980: (int) (TREE_REAL_CST (arg1) / 0x10000 / 0x10000)); ! 981: } ! 982: else if (TREE_CODE (type) == REAL_TYPE) ! 983: { ! 984: if (TREE_CODE (arg1) == INTEGER_CST) ! 985: t = build_real_from_int_cst (arg1); ! 986: else if (TREE_CODE (arg1) == REAL_CST) ! 987: t = build_real (TREE_REAL_CST (arg1)); ! 988: } ! 989: TREE_TYPE (t) = type; ! 990: TREE_LITERAL (t) = 1; ! 991: return t; ! 992: } ! 993: ! 994: /* Return nonzero if two constants (that are not manifest constants) ! 995: are necessarily equal. It detects only the easiest, common case of ! 996: equality. */ ! 997: ! 998: static int ! 999: operand_equal_p (arg0, arg1) ! 1000: tree arg0, arg1; ! 1001: { ! 1002: while ((TREE_CODE (arg0) == NOP_EXPR ! 1003: || TREE_CODE (arg0) == CONVERT_EXPR) ! 1004: && TYPE_MODE (TREE_TYPE (arg0)) == TYPE_MODE (TREE_TYPE (TREE_OPERAND (arg0, 0)))) ! 1005: arg0 = TREE_OPERAND (arg0, 0); ! 1006: while ((TREE_CODE (arg1) == NOP_EXPR ! 1007: || TREE_CODE (arg1) == CONVERT_EXPR) ! 1008: && TYPE_MODE (TREE_TYPE (arg1)) == TYPE_MODE (TREE_TYPE (TREE_OPERAND (arg1, 0)))) ! 1009: arg1 = TREE_OPERAND (arg1, 0); ! 1010: ! 1011: if (TREE_CODE (arg0) == TREE_CODE (arg1) ! 1012: && TREE_CODE (arg0) == ADDR_EXPR ! 1013: && TREE_OPERAND (arg0, 0) == TREE_OPERAND (arg1, 0)) ! 1014: return 1; ! 1015: return 0; ! 1016: } ! 1017: ! 1018: /* Perform constant folding and related simplification of EXPR. ! 1019: The related simplifications include x*1 => x, x*0 => 0, etc., ! 1020: and application of the associative law. ! 1021: NOP_EXPR conversions may be removed freely (as long as we ! 1022: are careful not to change the C type of the overall expression) ! 1023: We cannot simplify through a CONVERT_EXPR, FIX_EXPR or FLOAT_EXPR, ! 1024: but we can constant-fold them if they have constant operands. */ ! 1025: ! 1026: tree ! 1027: fold (expr) ! 1028: tree expr; ! 1029: { ! 1030: register tree t = expr; ! 1031: register tree arg0, arg1; ! 1032: register enum tree_code code = TREE_CODE (t); ! 1033: register int kind; ! 1034: ! 1035: /* WINS will be nonzero when the switch is done ! 1036: if all operands are constant. ! 1037: ! 1038: LOSES will be nonzero when the switch is done ! 1039: if any operand is volatile. ! 1040: This inhibits optimizations such as (foo () * 0) => 0. ! 1041: But identity-element optimizations such as ! 1042: (foo () * 1) => (foo ()) can be done even if LOSES is set. */ ! 1043: ! 1044: int wins = 1; ! 1045: int loses = 0; ! 1046: ! 1047: /* Return right away if already constant. */ ! 1048: if (TREE_LITERAL (t)) ! 1049: { ! 1050: if (code == CONST_DECL) ! 1051: return DECL_INITIAL (t); ! 1052: return t; ! 1053: } ! 1054: ! 1055: kind = *tree_code_type[(int) code]; ! 1056: if (kind == 'e' || kind == 'r') ! 1057: { ! 1058: register int len = tree_code_length[(int) code]; ! 1059: register int i; ! 1060: for (i = 0; i < len; i++) ! 1061: { ! 1062: if (TREE_OPERAND (t, i) == 0) ! 1063: continue; /* Valid for CALL_EXPR, at least. */ ! 1064: if (TREE_CODE (TREE_OPERAND (t, i)) != INTEGER_CST ! 1065: && TREE_CODE (TREE_OPERAND (t, i)) != REAL_CST) ! 1066: /* Note that TREE_LITERAL isn't enough: ! 1067: static var addresses are constant but we can't ! 1068: do arithmetic on them. */ ! 1069: wins = 0; ! 1070: if (TREE_VOLATILE (TREE_OPERAND (t, i))) ! 1071: loses = 1; ! 1072: } ! 1073: arg0 = TREE_OPERAND (t, 0); ! 1074: if (len > 1) ! 1075: arg1 = TREE_OPERAND (t, 1); ! 1076: } ! 1077: ! 1078: /* Now WINS and LOSES are set as described above, ! 1079: ARG0 is the first operand of EXPR, ! 1080: and ARG1 is the second operand (if it has more than one operand). */ ! 1081: ! 1082: switch (code) ! 1083: { ! 1084: case INTEGER_CST: ! 1085: case REAL_CST: ! 1086: case STRING_CST: ! 1087: case COMPLEX_CST: ! 1088: case CONSTRUCTOR: ! 1089: return t; ! 1090: ! 1091: case CONST_DECL: ! 1092: return fold (DECL_INITIAL (t)); ! 1093: ! 1094: case NOP_EXPR: ! 1095: case FLOAT_EXPR: ! 1096: case CONVERT_EXPR: ! 1097: case FIX_TRUNC_EXPR: ! 1098: /* Other kinds of FIX are not handled properly by fold_convert. */ ! 1099: if (!wins) ! 1100: { ! 1101: TREE_LITERAL (t) = TREE_LITERAL (arg0); ! 1102: return t; ! 1103: } ! 1104: return fold_convert (t); ! 1105: ! 1106: case RANGE_EXPR: ! 1107: TREE_LITERAL (t) = wins; ! 1108: return t; ! 1109: ! 1110: case NEGATE_EXPR: ! 1111: if (wins) ! 1112: { ! 1113: if (TREE_CODE (arg0) == INTEGER_CST) ! 1114: { ! 1115: if (TREE_INT_CST_LOW (arg0) == 0) ! 1116: t = build_int_2 (0, - TREE_INT_CST_HIGH (arg0)); ! 1117: else ! 1118: t = build_int_2 (- TREE_INT_CST_LOW (arg0), ! 1119: ~ TREE_INT_CST_HIGH (arg0)); ! 1120: force_fit_type (t); ! 1121: } ! 1122: else if (TREE_CODE (arg0) == REAL_CST) ! 1123: t = build_real (- TREE_REAL_CST (arg0)); ! 1124: TREE_TYPE (t) = TREE_TYPE (expr); ! 1125: } ! 1126: return t; ! 1127: ! 1128: case ABS_EXPR: ! 1129: if (wins) ! 1130: { ! 1131: if (TREE_CODE (arg0) == INTEGER_CST) ! 1132: { ! 1133: if (! TREE_UNSIGNED (TREE_TYPE (expr)) ! 1134: || TREE_INT_CST_HIGH (arg0) < 0) ! 1135: { ! 1136: if (TREE_INT_CST_LOW (arg0) == 0) ! 1137: t = build_int_2 (0, - TREE_INT_CST_HIGH (arg0)); ! 1138: else ! 1139: t = build_int_2 (- TREE_INT_CST_LOW (arg0), ! 1140: ~ TREE_INT_CST_HIGH (arg0)); ! 1141: } ! 1142: } ! 1143: else if (TREE_CODE (arg0) == REAL_CST) ! 1144: { ! 1145: if (TREE_REAL_CST (arg0) < 0) ! 1146: t = build_real (- TREE_REAL_CST (arg0)); ! 1147: } ! 1148: TREE_TYPE (t) = TREE_TYPE (expr); ! 1149: } ! 1150: return t; ! 1151: ! 1152: case BIT_NOT_EXPR: ! 1153: if (wins) ! 1154: { ! 1155: if (TREE_CODE (arg0) == INTEGER_CST) ! 1156: t = build_int_2 (~ TREE_INT_CST_LOW (arg0), ! 1157: ~ TREE_INT_CST_HIGH (arg0)); ! 1158: TREE_TYPE (t) = TREE_TYPE (expr); ! 1159: force_fit_type (t); ! 1160: } ! 1161: return t; ! 1162: ! 1163: case PLUS_EXPR: ! 1164: if (integer_zerop (arg0)) ! 1165: return convert (TREE_TYPE (expr), arg1); ! 1166: if (integer_zerop (arg1)) ! 1167: return convert (TREE_TYPE (expr), arg0); ! 1168: associate: ! 1169: /* In most languages, can't associate operations on floats ! 1170: through parentheses. Rather than remember where the parentheses ! 1171: were, we don't associate floats at all. It shouldn't matter much. */ ! 1172: if (TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE) ! 1173: goto binary; ! 1174: /* The varsign == -1 cases happen only for addition and subtraction. ! 1175: It says that the arg that was split was really CON minus VAR. ! 1176: The rest of the code applies to all associative operations. */ ! 1177: if (!wins) ! 1178: { ! 1179: tree var, con, tem; ! 1180: int varsign; ! 1181: tree inner_arg; ! 1182: ! 1183: if (split_tree (arg0, code, &var, &con, &varsign)) ! 1184: { ! 1185: if (varsign == -1) ! 1186: { ! 1187: /* EXPR is (CON-VAR) +- ARG1. */ ! 1188: /* If it is + and VAR==ARG1, return just CONST. */ ! 1189: if (code == PLUS_EXPR && operand_equal_p (var, arg1)) ! 1190: return con; ! 1191: ! 1192: /* Otherwise return (CON +- ARG1) - VAR. */ ! 1193: TREE_SET_CODE (t, MINUS_EXPR); ! 1194: TREE_OPERAND (t, 1) = var; ! 1195: TREE_OPERAND (t, 0) ! 1196: = fold (build (code, TREE_TYPE (t), con, arg1)); ! 1197: } ! 1198: else ! 1199: { ! 1200: /* EXPR is (VAR+CON) +- ARG1. */ ! 1201: /* If it is - and VAR==ARG1, return just CONST. */ ! 1202: if (code == MINUS_EXPR && operand_equal_p (var, arg1)) ! 1203: return con; ! 1204: ! 1205: /* Otherwise return VAR +- (ARG1 +- CON). */ ! 1206: TREE_OPERAND (t, 1) = tem ! 1207: = fold (build (code, TREE_TYPE (t), arg1, con)); ! 1208: TREE_OPERAND (t, 0) = var; ! 1209: if (integer_zerop (tem) ! 1210: && (code == PLUS_EXPR || code == MINUS_EXPR)) ! 1211: return var; ! 1212: /* If we have x +/- (c - d) [c an explicit integer] ! 1213: change it to x -/+ (d - c) since if d is relocatable ! 1214: then the latter can be a single immediate insn ! 1215: and the former cannot. */ ! 1216: if (TREE_CODE (tem) == MINUS_EXPR ! 1217: && TREE_CODE (TREE_OPERAND (tem, 0)) == INTEGER_CST) ! 1218: { ! 1219: tree tem1 = TREE_OPERAND (tem, 1); ! 1220: TREE_OPERAND (tem, 1) = TREE_OPERAND (tem, 0); ! 1221: TREE_OPERAND (tem, 0) = tem1; ! 1222: TREE_SET_CODE (t, ! 1223: (code == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR)); ! 1224: } ! 1225: } ! 1226: return t; ! 1227: } ! 1228: ! 1229: if (split_tree (arg1, code, &var, &con, &varsign)) ! 1230: { ! 1231: /* EXPR is ARG0 +- (CON +- VAR). */ ! 1232: if (varsign == -1) ! 1233: TREE_SET_CODE (t, ! 1234: (code == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR)); ! 1235: if (TREE_CODE (t) == MINUS_EXPR && operand_equal_p (var, arg0)) ! 1236: return con; ! 1237: TREE_OPERAND (t, 0) ! 1238: = fold (build (code, TREE_TYPE (t), arg0, con)); ! 1239: TREE_OPERAND (t, 1) = var; ! 1240: if (integer_zerop (TREE_OPERAND (t, 0)) ! 1241: && TREE_CODE (t) == PLUS_EXPR) ! 1242: return var; ! 1243: return t; ! 1244: } ! 1245: } ! 1246: binary: ! 1247: { ! 1248: register tree t1 = NULL_TREE; ! 1249: if (wins) ! 1250: t1 = combine (code, arg0, arg1); ! 1251: if (t1 != NULL_TREE) return t1; ! 1252: return t; ! 1253: } ! 1254: ! 1255: case MINUS_EXPR: ! 1256: if (! wins && integer_zerop (arg0)) ! 1257: return build (NEGATE_EXPR, TREE_TYPE (expr), arg1); ! 1258: if (integer_zerop (arg1)) ! 1259: return convert (TREE_TYPE (expr), arg0); ! 1260: /* Fold &x - &x. This can happen from &x.foo - &x. */ ! 1261: if (operand_equal_p (arg0, arg1)) ! 1262: return convert (TREE_TYPE (t), integer_zero_node); ! 1263: goto associate; ! 1264: ! 1265: case MULT_EXPR: ! 1266: if (!loses && integer_zerop (arg0)) ! 1267: return convert (TREE_TYPE (expr), arg0); ! 1268: if (!loses && integer_zerop (arg1)) ! 1269: return convert (TREE_TYPE (expr), arg1); ! 1270: if (integer_onep (arg0)) ! 1271: return convert (TREE_TYPE (expr), arg1); ! 1272: if (integer_onep (arg1)) ! 1273: return convert (TREE_TYPE (expr), arg0); ! 1274: goto associate; ! 1275: ! 1276: case BIT_IOR_EXPR: ! 1277: if (!loses && integer_all_onesp (arg0)) ! 1278: return convert (TREE_TYPE (expr), arg0); ! 1279: if (!loses && integer_all_onesp (arg1)) ! 1280: return convert (TREE_TYPE (expr), arg1); ! 1281: case BIT_XOR_EXPR: ! 1282: if (integer_zerop (arg0)) ! 1283: return convert (TREE_TYPE (expr), arg1); ! 1284: if (integer_zerop (arg1)) ! 1285: return convert (TREE_TYPE (expr), arg0); ! 1286: goto associate; ! 1287: ! 1288: case BIT_AND_EXPR: ! 1289: if (integer_all_onesp (arg0)) ! 1290: return convert (TREE_TYPE (expr), arg1); ! 1291: if (integer_all_onesp (arg1)) ! 1292: return convert (TREE_TYPE (expr), arg0); ! 1293: if (!loses && integer_zerop (arg0)) ! 1294: return convert (TREE_TYPE (expr), arg0); ! 1295: if (!loses && integer_zerop (arg1)) ! 1296: return convert (TREE_TYPE (expr), arg1); ! 1297: /* Simplify (int)((unsigned char)x & 0x377) into (int)(unsigned char)x. */ ! 1298: if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == NOP_EXPR ! 1299: && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg1, 0)))) ! 1300: { ! 1301: int prec = TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg1, 0))); ! 1302: if (prec < BITS_PER_WORD && prec < HOST_BITS_PER_INT ! 1303: && (~TREE_INT_CST_LOW (arg0) & ((1 << prec) - 1)) == 0) ! 1304: return convert (TREE_TYPE (expr), arg1); ! 1305: } ! 1306: if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg0) == NOP_EXPR ! 1307: && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg0, 0)))) ! 1308: { ! 1309: int prec = TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0))); ! 1310: if (prec < BITS_PER_WORD && prec < HOST_BITS_PER_INT ! 1311: && (~TREE_INT_CST_LOW (arg1) & ((1 << prec) - 1)) == 0) ! 1312: return convert (TREE_TYPE (expr), arg0); ! 1313: } ! 1314: goto associate; ! 1315: ! 1316: case BIT_ANDTC_EXPR: ! 1317: if (integer_all_onesp (arg0)) ! 1318: return convert (TREE_TYPE (expr), arg1); ! 1319: if (integer_zerop (arg1)) ! 1320: return convert (TREE_TYPE (expr), arg0); ! 1321: if (!loses && integer_zerop (arg0)) ! 1322: return convert (TREE_TYPE (expr), arg0); ! 1323: if (!loses && integer_all_onesp (arg1)) ! 1324: return combine (code, arg1, arg1); ! 1325: goto binary; ! 1326: ! 1327: case TRUNC_DIV_EXPR: ! 1328: case ROUND_DIV_EXPR: ! 1329: case FLOOR_DIV_EXPR: ! 1330: case CEIL_DIV_EXPR: ! 1331: case RDIV_EXPR: ! 1332: if (integer_onep (arg1)) ! 1333: return convert (TREE_TYPE (expr), arg0); ! 1334: goto binary; ! 1335: ! 1336: case CEIL_MOD_EXPR: ! 1337: case FLOOR_MOD_EXPR: ! 1338: case ROUND_MOD_EXPR: ! 1339: case TRUNC_MOD_EXPR: ! 1340: if (!loses && integer_onep (arg1)) ! 1341: return combine (code, arg1, arg1); ! 1342: goto binary; ! 1343: ! 1344: case LSHIFT_EXPR: ! 1345: case RSHIFT_EXPR: ! 1346: case LROTATE_EXPR: ! 1347: case RROTATE_EXPR: ! 1348: if (integer_zerop (arg1)) ! 1349: return convert (TREE_TYPE (expr), arg0); ! 1350: goto binary; ! 1351: ! 1352: case MIN_EXPR: case MAX_EXPR: ! 1353: goto associate; ! 1354: ! 1355: case TRUTH_NOT_EXPR: ! 1356: if (wins) ! 1357: { ! 1358: if (TREE_CODE (arg0) == INTEGER_CST) ! 1359: { ! 1360: t = build_int_2 ((TREE_INT_CST_LOW (arg0) == 0 ! 1361: && TREE_INT_CST_HIGH (arg0) == 0), ! 1362: 0); ! 1363: TREE_TYPE (t) = integer_type_node; ! 1364: } ! 1365: if (TREE_CODE (arg0) == REAL_CST) ! 1366: { ! 1367: t = build_int_2 (TREE_REAL_CST (arg0) == 0, 0); ! 1368: TREE_TYPE (t) = integer_type_node; ! 1369: } ! 1370: } ! 1371: return t; ! 1372: ! 1373: case TRUTH_AND_EXPR: ! 1374: case TRUTH_ANDIF_EXPR: ! 1375: if (wins) ! 1376: { ! 1377: if (TREE_CODE (arg0) == INTEGER_CST ! 1378: && TREE_CODE (arg1) == INTEGER_CST) ! 1379: t = build_int_2 (((TREE_INT_CST_LOW (arg0) || TREE_INT_CST_HIGH (arg0)) ! 1380: && (TREE_INT_CST_LOW (arg1) || TREE_INT_CST_HIGH (arg1))), ! 1381: 0); ! 1382: if (TREE_CODE (arg0) == REAL_CST ! 1383: && TREE_CODE (arg1) == REAL_CST) ! 1384: t = build_int_2 ((TREE_REAL_CST (arg0) && TREE_REAL_CST (arg1)), ! 1385: 0); ! 1386: TREE_TYPE (t) = TREE_TYPE (expr); ! 1387: } ! 1388: return t; ! 1389: ! 1390: case TRUTH_OR_EXPR: ! 1391: case TRUTH_ORIF_EXPR: ! 1392: if (wins) ! 1393: { ! 1394: if (TREE_CODE (arg0) == INTEGER_CST ! 1395: && TREE_CODE (arg1) == INTEGER_CST) ! 1396: t = build_int_2 (((TREE_INT_CST_LOW (arg0) || TREE_INT_CST_HIGH (arg0)) ! 1397: || (TREE_INT_CST_LOW (arg1) || TREE_INT_CST_HIGH (arg1))), ! 1398: 0); ! 1399: if (TREE_CODE (arg0) == REAL_CST && TREE_CODE (arg1) == REAL_CST) ! 1400: t = build_int_2 ((TREE_REAL_CST (arg0) || TREE_REAL_CST (arg1)), ! 1401: 0); ! 1402: TREE_TYPE (t) = TREE_TYPE (expr); ! 1403: } ! 1404: return t; ! 1405: ! 1406: case EQ_EXPR: ! 1407: case NE_EXPR: ! 1408: case LT_EXPR: ! 1409: case GT_EXPR: ! 1410: case LE_EXPR: ! 1411: case GE_EXPR: ! 1412: /* Convert foo++ == CONST into ++foo == CONST + INCR. ! 1413: First, see if one arg is constant; find the constant arg ! 1414: and the other one. */ ! 1415: { ! 1416: tree constop = 0, varop; ! 1417: tree *constoploc; ! 1418: ! 1419: if (TREE_LITERAL (arg1)) ! 1420: constoploc = &TREE_OPERAND (t, 1), constop = arg1, varop = arg0; ! 1421: if (TREE_LITERAL (arg0)) ! 1422: constoploc = &TREE_OPERAND (t, 0), constop = arg0, varop = arg1; ! 1423: ! 1424: if (constop && TREE_CODE (varop) == POSTINCREMENT_EXPR) ! 1425: { ! 1426: tree newconst ! 1427: = fold (build (PLUS_EXPR, TREE_TYPE (t), ! 1428: constop, TREE_OPERAND (varop, 1))); ! 1429: /* This optimization is invalid for ordered comparisons ! 1430: if CONST+INCR overflows! ! 1431: We can assume that address + integer will not overflow. */ ! 1432: if (TREE_CODE (newconst) != INTEGER_CST ! 1433: || ! tree_int_cst_lt (newconst, constop) ! 1434: || code == EQ_EXPR || code == NE_EXPR) ! 1435: { ! 1436: TREE_CODE (varop) = PREINCREMENT_EXPR; ! 1437: *constoploc = newconst; ! 1438: return t; ! 1439: } ! 1440: } ! 1441: else if (constop && TREE_CODE (varop) == POSTDECREMENT_EXPR) ! 1442: { ! 1443: tree newconst ! 1444: = fold (build (MINUS_EXPR, TREE_TYPE (t), ! 1445: constop, TREE_OPERAND (varop, 1))); ! 1446: if (TREE_CODE (newconst) != INTEGER_CST ! 1447: || tree_int_cst_lt (newconst, constop) ! 1448: || code == EQ_EXPR || code == NE_EXPR) ! 1449: { ! 1450: TREE_CODE (varop) = PREDECREMENT_EXPR; ! 1451: *constoploc = newconst; ! 1452: return t; ! 1453: } ! 1454: } ! 1455: } ! 1456: ! 1457: /* An unsigned comparison against 0 can be simplified. */ ! 1458: if (integer_zerop (arg0) ! 1459: && (TREE_CODE (TREE_TYPE (arg0)) == INTEGER_TYPE ! 1460: || TREE_CODE (TREE_TYPE (arg0)) == POINTER_TYPE) ! 1461: && TREE_UNSIGNED (TREE_TYPE (arg0))) ! 1462: { ! 1463: switch (TREE_CODE (t)) ! 1464: { ! 1465: case LT_EXPR: ! 1466: TREE_CODE (t) = NE_EXPR; ! 1467: break; ! 1468: case GE_EXPR: ! 1469: TREE_CODE (t) = EQ_EXPR; ! 1470: break; ! 1471: case LE_EXPR: ! 1472: return build (COMPOUND_EXPR, integer_type_node, ! 1473: arg1, integer_one_node); ! 1474: case GT_EXPR: ! 1475: return build (COMPOUND_EXPR, integer_type_node, ! 1476: arg1, integer_zero_node); ! 1477: } ! 1478: } ! 1479: ! 1480: /* An unsigned comparison against 0 can be simplified. */ ! 1481: if (integer_zerop (arg1) ! 1482: && (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE ! 1483: || TREE_CODE (TREE_TYPE (arg1)) == POINTER_TYPE) ! 1484: && TREE_UNSIGNED (TREE_TYPE (arg1))) ! 1485: { ! 1486: switch (TREE_CODE (t)) ! 1487: { ! 1488: case GT_EXPR: ! 1489: TREE_CODE (t) = NE_EXPR; ! 1490: break; ! 1491: case LE_EXPR: ! 1492: TREE_CODE (t) = EQ_EXPR; ! 1493: break; ! 1494: case GE_EXPR: ! 1495: return build (COMPOUND_EXPR, integer_type_node, ! 1496: arg0, integer_one_node); ! 1497: case LT_EXPR: ! 1498: return build (COMPOUND_EXPR, integer_type_node, ! 1499: arg0, integer_zero_node); ! 1500: } ! 1501: } ! 1502: ! 1503: /* To compute GT, swap the arguments and do LT. ! 1504: To compute GE, do LT and invert the result. ! 1505: To compute LE, swap the arguments, do LT and invert the result. ! 1506: To compute NE, do EQ and invert the result. */ ! 1507: if (code == LE_EXPR || code == GT_EXPR) ! 1508: { ! 1509: register tree temp = arg0; ! 1510: arg0 = arg1; ! 1511: arg1 = temp; ! 1512: } ! 1513: ! 1514: /* Compute a result for LT or EQ if args permit. */ ! 1515: if (TREE_CODE (arg0) == INTEGER_CST ! 1516: && TREE_CODE (arg1) == INTEGER_CST) ! 1517: { ! 1518: if (code == EQ_EXPR || code == NE_EXPR) ! 1519: t = build_int_2 ! 1520: (TREE_INT_CST_LOW (arg0) == TREE_INT_CST_LOW (arg1) ! 1521: && TREE_INT_CST_HIGH (arg0) == TREE_INT_CST_HIGH (arg1), ! 1522: 0); ! 1523: else ! 1524: t = build_int_2 ((TREE_UNSIGNED (TREE_TYPE (arg0)) ! 1525: ? INT_CST_LT_UNSIGNED (arg0, arg1) ! 1526: : INT_CST_LT (arg0, arg1)), ! 1527: 0); ! 1528: } ! 1529: else if (TREE_CODE (arg0) == REAL_CST ! 1530: && TREE_CODE (arg1) == REAL_CST) ! 1531: { ! 1532: if (code == EQ_EXPR || code == NE_EXPR) ! 1533: t = build_int_2 (TREE_REAL_CST (arg0) == TREE_REAL_CST (arg1), 0); ! 1534: else ! 1535: t = build_int_2 (TREE_REAL_CST (arg0) < TREE_REAL_CST (arg1), 0); ! 1536: } ! 1537: else ! 1538: return t; ! 1539: ! 1540: /* If we wanted ...-or-equal, invert the result. */ ! 1541: if (code == GE_EXPR || code == LE_EXPR || code == NE_EXPR) ! 1542: TREE_INT_CST_LOW (t) ^= 1; ! 1543: TREE_TYPE (t) = TREE_TYPE (expr); ! 1544: return t; ! 1545: ! 1546: COND_EXPR: ! 1547: if (TREE_LITERAL (arg0)) ! 1548: return TREE_OPERAND (expr, (integer_zerop (arg0) ? 2 : 1)); ! 1549: return t; ! 1550: ! 1551: default: ! 1552: return t; ! 1553: } /* switch (code) */ ! 1554: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.