3 * File name: ir/opt/opt_confirms.c
4 * Purpose: Optimizations regarding Confirm nodes
9 * Copyright: (c) 1998-2005 Universität Karlsruhe
10 * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
19 #include "iropt_dbg.h"
20 #include "opt_confirms.h"
23 MIN_INCLUDED = 0x00, /**< [min, ... */
24 MAX_INCLUDED = 0x00, /**< ..., max] */
25 MIN_EXCLUDED = 0x01, /**< (min, ... */
26 MAX_EXCLUDED = 0x02 /**< ..., max) */
30 * An interval. We could use
31 * intervals that ALWAYS include its borders, even for
32 * floating point, as the precision is limited.
33 * However, as our tarval module did not support
34 * such kind of operation, we use border flags allowing
37 typedef struct _interval_t {
38 tarval *min; /**< lowest border */
39 tarval *max; /**< highest border */
40 unsigned char flags; /**< border flags */
44 * Check, if the value of a node is != 0.
46 * This is a often needed case, so we handle here Confirm
49 int value_not_zero(ir_node *n)
51 #define RET_ON(x) if (x) return 1; break
54 ir_mode *mode = get_irn_mode(n);
57 while (get_irn_op(n) == op_Confirm) {
59 * Note: A Confirm is never after a Const. So,
60 * we simply can check the bound for beeing a Const
61 * without the fear that is might be hidden by a further Confirm.
63 tv = value_of(get_Confirm_bound(n));
67 pnc = tarval_cmp(tv, get_mode_null(mode));
70 * Beware: C might by a NaN. It is not clear, what we should do
71 * than. Of course a NaN is != 0, but we might use this function
72 * to remove up Exceptions, and NaN's might generate Exception.
73 * So, we do NOT handle NaNs here for safety.
75 * Note that only the C != 0 case need additional checking.
77 switch (get_Confirm_cmp(n)) {
78 case pn_Cmp_Eq: /* n == C /\ C != 0 ==> n != 0 */
79 RET_ON(pnc != pn_Cmp_Eq && pnc != pn_Cmp_Uo);
80 case pn_Cmp_Lg: /* n != C /\ C == 0 ==> n != 0 */
81 RET_ON(pnc == pn_Cmp_Eq);
82 case pn_Cmp_Lt: /* n < C /\ C <= 0 ==> n != 0 */
83 RET_ON(pnc == pn_Cmp_Lt || pnc == pn_Cmp_Eq);
84 case pn_Cmp_Le: /* n <= C /\ C < 0 ==> n != 0 */
85 RET_ON(pnc == pn_Cmp_Lt);
86 case pn_Cmp_Ge: /* n >= C /\ C > 0 ==> n != 0 */
87 RET_ON(pnc == pn_Cmp_Gt);
88 case pn_Cmp_Gt: /* n > C /\ C >= 0 ==> n != 0 */
89 RET_ON(pnc == pn_Cmp_Gt || pnc == pn_Cmp_Eq);
94 /* there might be several Confirms one after other that form an interval */
95 n = get_Confirm_value(n);
102 pnc = tarval_cmp(tv, get_mode_null(mode));
104 /* again, need check for NaN */
105 return (pnc != pn_Cmp_Eq) && (pnc != pn_Cmp_Uo);
111 * Check, if the value of a node can be confirmed >= 0 or <= 0,
112 * If the mode of the value did not honor signed zeros, else
113 * check for >= 0 or < 0.
115 value_classify classify_value_sign(ir_node *n)
121 if (get_irn_op(n) != op_Confirm)
122 return VALUE_UNKNOWN;
124 tv = value_of(get_Confirm_bound(n));
125 if (tv == tarval_bad)
126 return VALUE_UNKNOWN;
128 mode = get_irn_mode(n);
131 * We can handle only >=, >, <, <= cases.
132 * We could handle == too, but this will be optimized into
135 * Note that for integer modes we have a slightly better
136 * optimization possibilities, so we handle this
139 cmp = get_Confirm_cmp(n);
144 * must be x < c <= 1 to be useful if integer mode and -0 = 0
145 * x < c <= 0 to be useful else
149 * must be x <= c < 1 to be useful if integer mode and -0 = 0
150 * x <= c < 0 to be useful else
152 c = mode_is_int(mode) && mode_honor_signed_zeros(mode) ?
153 get_mode_one(mode) : get_mode_null(mode);
155 ncmp = tarval_cmp(tv, c);
156 if (ncmp == pn_Cmp_Eq)
159 if (cmp != (ncmp ^ pn_Cmp_Eq))
160 return VALUE_UNKNOWN;
163 return VALUE_NEGATIVE;
167 * must be x >= c > -1 to be useful if integer mode
168 * x >= c >= 0 to be useful else
172 * must be x > c >= -1 to be useful if integer mode
173 * x > c >= 0 to be useful else
175 if (mode_is_int(mode)) {
176 c = get_mode_minus_one(mode);
178 ncmp = tarval_cmp(tv, c);
179 if (ncmp == pn_Cmp_Eq)
182 if (cmp != (ncmp ^ pn_Cmp_Eq))
183 return VALUE_UNKNOWN;
186 c = get_mode_minus_one(mode);
188 ncmp = tarval_cmp(tv, c);
190 if (ncmp != pn_Cmp_Eq && ncmp != pn_Cmp_Gt)
191 return VALUE_UNKNOWN;
195 return VALUE_POSITIVE;
198 return VALUE_UNKNOWN;
203 * construct an interval from a value
205 * @return the filled interval or NULL if no interval
206 * can be created (happens only on floating point
208 static interval_t *get_interval_from_tv(interval_t *iv, tarval *tv)
210 ir_mode *mode = get_tarval_mode(tv);
212 if (tv == tarval_bad) {
213 if (mode_is_float(mode)) {
214 /* NaN could be included which we cannot handle */
215 iv->min = tarval_bad;
216 iv->max = tarval_bad;
217 iv->flags = MIN_EXCLUDED | MAX_EXCLUDED;
222 iv->min = get_mode_min(mode);
223 iv->max = get_mode_max(mode);
224 iv->flags = MIN_INCLUDED | MAX_INCLUDED;
229 if (mode_is_float(mode)) {
230 if (tv == get_mode_NAN(mode)) {
231 /* arg, we cannot handle NaN's. */
232 iv->min = tarval_bad;
233 iv->max = tarval_bad;
234 iv->flags = MIN_EXCLUDED | MAX_EXCLUDED;
242 iv->flags = MIN_INCLUDED | MAX_INCLUDED;
248 * construct an interval from a Confirm
250 * @param iv an empty interval, will be filled
251 * @param bound the bound value
252 * @param pnc the Confirm pnc relation
254 * @return the filled interval or NULL if no interval
255 * can be created (happens only on floating point
257 static interval_t *get_interval(interval_t *iv, ir_node *bound, pn_Cmp pnc)
259 ir_mode *mode = get_irn_mode(bound);
260 tarval *tv = value_of(bound);
262 if (tv == tarval_bad) {
263 /* There is nothing we could do here. For integer
264 * modes we could return [-oo, +oo], but there is
265 * nothing we could deduct from such an interval.
266 * So, speed things up and return unknown.
268 iv->min = tarval_bad;
269 iv->max = tarval_bad;
270 iv->flags = MIN_EXCLUDED | MAX_EXCLUDED;
274 if (mode_is_float(mode)) {
275 if (tv == get_mode_NAN(mode)) {
276 /* arg, we cannot handle NaN's. */
277 iv->min = tarval_bad;
278 iv->max = tarval_bad;
279 iv->flags = MIN_EXCLUDED | MAX_EXCLUDED;
285 /* check which side is known */
291 iv->flags = MIN_INCLUDED | MAX_INCLUDED;
296 iv->min = get_mode_min(mode);
298 iv->flags = MIN_INCLUDED | MAX_INCLUDED;
303 iv->min = get_mode_min(mode);
305 iv->flags = MIN_INCLUDED | MAX_EXCLUDED;
311 iv->max = get_mode_max(mode);
312 iv->flags = MIN_EXCLUDED | MAX_INCLUDED;
318 iv->max = get_mode_max(mode);
319 iv->flags = MIN_INCLUDED | MAX_INCLUDED;
324 * Ordered means, that at least neither
325 * our bound nor our value ara NaN's
328 iv->min = get_mode_min(mode);
329 iv->max = get_mode_max(mode);
330 iv->flags = MIN_INCLUDED | MAX_INCLUDED;
335 * We do not handle UNORDERED, as a NaN
336 * could be included in the interval.
338 iv->min = tarval_bad;
339 iv->max = tarval_bad;
340 iv->flags = MIN_EXCLUDED | MAX_EXCLUDED;
344 if (iv->min != tarval_bad && iv->max != tarval_bad)
350 * Try to evaluate l_iv pnc r_iv.
352 * @param l_iv the left interval
353 * @param r_iv the right interval
354 * @param pnc the compare relation
357 * tarval_b_true or tarval_b_false it it can be evaluated,
360 static tarval *compare_iv(const interval_t *l_iv, const interval_t *r_iv, pn_Cmp pnc)
364 tarval *tv_true = tarval_b_true, *tv_false = tarval_b_false;
366 /* if one interval contains NaNs, we cannot evaluate anything */
367 if (! l_iv || ! r_iv)
370 /* we can only check ordered relations */
371 if (pnc & pn_Cmp_Uo) {
374 pnc = get_negated_pnc(pnc, get_tarval_mode(l_iv->min));
380 /* if we have > or >=, we do the inverse to save some cases */
381 if (pnc == pn_Cmp_Ge || pnc == pn_Cmp_Gt) {
384 pnc = get_inversed_pnc(pnc);
390 /* now, only the following cases remains */
393 /* two intervals can be compared for equality only if they are a single value */
394 if (l_iv->min == l_iv->max && r_iv->min == r_iv->max)
395 return tarval_cmp(l_iv->min, r_iv->min) == pn_Cmp_Eq ? tv_true : tv_false;
399 /* two intervals can be compared for not equality only if they are a single value */
400 if (l_iv->min == l_iv->max && r_iv->min == r_iv->max)
401 return tarval_cmp(l_iv->min, r_iv->min) != pn_Cmp_Eq ? tv_true : tv_false;
405 res = tarval_cmp(l_iv->max, r_iv->min);
407 /* [a, b] < [c, d] <==> b < c */
408 if (res == pn_Cmp_Lt)
411 /* if one border is excluded, b <= c is enough */
412 if ((l_iv->flags & MAX_EXCLUDED || r_iv->flags & MIN_EXCLUDED) &&
416 /* [a, b] >= [c, d] <==> a > d */
417 res = tarval_cmp(l_iv->min, r_iv->max);
418 if (res == pn_Cmp_Gt)
421 /* if one border is excluded, a >= d is enough */
422 if ((l_iv->flags & MIN_EXCLUDED || r_iv->flags & MAX_EXCLUDED) &&
428 /* [a, b) <= [c, d] or [a, b] <= (c, d] <==> b <= c */
429 flags = (l_iv->flags & MAX_EXCLUDED) | (r_iv->flags & MIN_EXCLUDED);
431 res = tarval_cmp(l_iv->max, r_iv->min);
433 if (res == pn_Cmp_Lt || res == pn_Cmp_Eq)
437 res = tarval_cmp(l_iv->min, r_iv->max);
439 /* [a, b] > [c, d] <==> a > d */
440 if (res == pn_Cmp_Gt)
443 /* if one border is excluded, a >= d is enough */
444 if ((l_iv->flags & MIN_EXCLUDED || r_iv->flags & MAX_EXCLUDED) &&
450 /* Hmm. if both are intervals, we can find an order */
460 * Return the value of a Cmp if one or both predecessors
463 * @param left the left operand of the Cmp
464 * @param right the right operand of the Cmp
466 tarval *computed_value_Cmp_Confirm(ir_node *cmp, ir_node *left, ir_node *right, pn_Cmp pnc)
470 interval_t l_iv, r_iv;
473 if (get_irn_op(right) == op_Confirm) {
476 /* we want the Confirm on the left side */
481 pnc = get_inversed_pnc(pnc);
483 else if (get_irn_op(left) != op_Confirm) {
484 /* no Confirm on either one side, finish */
488 /* ok, here at least left is a Confirm, right might be */
489 l_bound = get_Confirm_bound(left);
490 l_pnc = get_Confirm_cmp(left);
492 if (get_irn_op(right) == op_Confirm) {
494 * both sides are Confirm's. Check some rare cases first.
496 ir_node *r_bound = get_Confirm_bound(right);
497 pn_Cmp r_pnc = get_Confirm_cmp(right);
500 * check for == or != can sometime be made WITHOUT constant bounds
503 if (! mode_is_float(get_irn_mode(left)) &&
504 (pnc == pn_Cmp_Eq || pnc == pn_Cmp_Lg)) {
505 /* l == r if bound(l) == bound(r) AND pnc(l) == pnc(r) == '=' */
506 if (r_bound == l_bound && r_pnc == l_pnc && r_pnc == pn_Cmp_Eq) {
507 DBG_EVAL_CONFIRM(cmp);
508 return pnc == pn_Cmp_Eq ? tarval_b_true : tarval_b_false;
512 * Here, we check only the right Confirm, as the left Confirms are
513 * checked later anyway.
516 if (left == r_bound && (r_pnc == pn_Cmp_Eq || r_pnc == pn_Cmp_Lg)) {
517 /* l == bound(r) AND pnc(r) == pnc */
519 DBG_EVAL_CONFIRM(cmp);
520 return tarval_b_true;
522 /* l == bound(r) AND pnc(r) != pnc */
524 DBG_EVAL_CONFIRM(cmp);
525 return tarval_b_false;
530 /* now, try interval magic */
532 get_interval(&l_iv, l_bound, l_pnc),
533 get_interval(&r_iv, r_bound, r_pnc),
536 if (tv != tarval_bad) {
537 DBG_EVAL_CONFIRM(cmp);
542 /* from Here, check only left Confirm */
545 * checks for == or != can sometime be made WITHOUT constant bounds
548 if (! mode_is_float(get_irn_mode(left)) &&
549 (pnc == pn_Cmp_Eq || pnc == pn_Cmp_Lg)) {
550 if (right == l_bound && (l_pnc == pn_Cmp_Eq || l_pnc == pn_Cmp_Lg)) {
551 /* r == bound(l) AND pnc(l) == pnc */
553 DBG_EVAL_CONFIRM(cmp);
554 return tarval_b_true;
556 /* r == bound(l) AND pnc(l) != pnc */
558 DBG_EVAL_CONFIRM(cmp);
559 return tarval_b_false;
564 /* now, only right == Const can help */
565 tv = value_of(right);
567 if (tv != tarval_bad) {
569 get_interval(&l_iv, l_bound, l_pnc),
570 get_interval_from_tv(&r_iv, tv),
574 if (tv != tarval_bad)
575 DBG_EVAL_CONFIRM(cmp);
580 /** For debugging. Prints an interval */
581 static void print_iv(const interval_t *iv) {
582 char smin[64], smax[64];
584 tarval_snprintf(smin, sizeof(smin), iv->min);
585 tarval_snprintf(smax, sizeof(smax), iv->max);
587 printf("%c%s, %s%c\n",
588 iv->flags & MIN_EXCLUDED ? '(' : '[',
590 iv->flags & MAX_EXCLUDED ? ')' : ']'