|
|
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.