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 if (mode_is_float(mode)) {
264 /* NaN could be included which we cannot handle */
265 iv->min = tarval_bad;
266 iv->max = tarval_bad;
267 iv->flags = MIN_EXCLUDED | MAX_EXCLUDED;
272 iv->min = get_mode_min(mode);
273 iv->max = get_mode_max(mode);
274 iv->flags = MIN_INCLUDED | MAX_INCLUDED;
279 if (mode_is_float(mode)) {
280 if (tv == get_mode_NAN(mode)) {
281 /* arg, we cannot handle NaN's. */
282 iv->min = tarval_bad;
283 iv->max = tarval_bad;
284 iv->flags = MIN_EXCLUDED | MAX_EXCLUDED;
290 /* check which side is known */
296 iv->flags = MIN_INCLUDED | MAX_INCLUDED;
301 iv->min = get_mode_min(mode);
303 iv->flags = MIN_INCLUDED | MAX_INCLUDED;
308 iv->min = get_mode_min(mode);
310 iv->flags = MIN_INCLUDED | MAX_EXCLUDED;
316 iv->max = get_mode_max(mode);
317 iv->flags = MIN_EXCLUDED | MAX_INCLUDED;
323 iv->max = get_mode_max(mode);
324 iv->flags = MIN_INCLUDED | MAX_INCLUDED;
329 * Ordered means, that at least neither
330 * our bound nor our value ara NaN's
333 iv->min = get_mode_min(mode);
334 iv->max = get_mode_max(mode);
335 iv->flags = MIN_INCLUDED | MAX_INCLUDED;
340 * We do not handle UNORDERED, as a NaN
341 * could be included in the interval.
343 iv->min = tarval_bad;
344 iv->max = tarval_bad;
345 iv->flags = MIN_EXCLUDED | MAX_EXCLUDED;
351 * Try to evaluate l_iv pnc r_iv.
353 * @param l_iv the left interval
354 * @param r_iv the right interval
355 * @param pnc the compare relation
358 * tarval_b_true or tarval_b_false it it can be evaluated,
361 static tarval *compare_iv(const interval_t *l_iv, const interval_t *r_iv, pn_Cmp pnc)
365 tarval *tv_true = tarval_b_true, *tv_false = tarval_b_false;
367 /* if one interval contains NaNs, we cannot evaluate anything */
368 if (! l_iv || ! r_iv)
371 /* we can only check ordered relations */
372 if (pnc & pn_Cmp_Uo) {
375 pnc = get_negated_pnc(pnc);
381 /* if we have > or >=, we do the inverse to save some cases */
382 if (pnc == pn_Cmp_Ge || pnc == pn_Cmp_Gt) {
385 pnc = get_inversed_pnc(pnc);
391 /* now, only the following cases remains */
394 /* two intervals can be compared for equality only if they are a single value */
395 if (l_iv->min == l_iv->max && r_iv->min == r_iv->max)
396 return tarval_cmp(l_iv->min, r_iv->min) == pn_Cmp_Eq ? tv_true : tv_false;
400 /* two intervals can be compared for not equality only if they are a single value */
401 if (l_iv->min == l_iv->max && r_iv->min == r_iv->max)
402 return tarval_cmp(l_iv->min, r_iv->min) != pn_Cmp_Eq ? tv_true : tv_false;
406 res = tarval_cmp(l_iv->max, r_iv->min);
408 /* [a, b] < [c, d] <==> b < c */
409 if (res == pn_Cmp_Lt)
412 /* if one border is excluded, b <= c is enough */
413 if ((l_iv->flags & MAX_EXCLUDED || r_iv->flags & MIN_EXCLUDED) &&
417 /* [a, b] >= [c, d] <==> a > d */
418 res = tarval_cmp(l_iv->min, r_iv->max);
419 if (res == pn_Cmp_Gt)
422 /* if one border is excluded, a >= d is enough */
423 if ((l_iv->flags & MIN_EXCLUDED || r_iv->flags & MAX_EXCLUDED) &&
429 /* [a, b) <= [c, d] or [a, b] <= (c, d] <==> b <= c */
430 flags = (l_iv->flags & MAX_EXCLUDED) | (r_iv->flags & MIN_EXCLUDED);
432 res = tarval_cmp(l_iv->max, r_iv->min);
434 if (res == pn_Cmp_Lt || res == pn_Cmp_Eq)
438 res = tarval_cmp(l_iv->min, r_iv->max);
440 /* [a, b] > [c, d] <==> a > d */
441 if (res == pn_Cmp_Gt)
444 /* if one border is excluded, a >= d is enough */
445 if ((l_iv->flags & MIN_EXCLUDED || r_iv->flags & MAX_EXCLUDED) &&
451 /* Hmm. if both are intervals, we can find an order */
461 * Return the value of a Cmp if one or both predecessors
464 * @param left the left operand of the Cmp
465 * @param right the right operand of the Cmp
467 tarval *computed_value_Cmp_Confirm(ir_node *cmp, ir_node *left, ir_node *right, pn_Cmp pnc)
471 interval_t l_iv, r_iv;
474 if (get_irn_op(right) == op_Confirm) {
477 /* we want the Confirm on the left side */
482 pnc = get_inversed_pnc(pnc);
484 else if (get_irn_op(left) != op_Confirm) {
485 /* no Confirm on either one side, finish */
489 /* ok, here at least left is a Confirm, right might be */
490 l_bound = get_Confirm_bound(left);
491 l_pnc = get_Confirm_cmp(left);
493 if (get_irn_op(right) == op_Confirm) {
495 * both sides are Confirm's. Check some rare cases first.
497 ir_node *r_bound = get_Confirm_bound(right);
498 pn_Cmp r_pnc = get_Confirm_cmp(right);
501 * check for == or != can sometime be made WITHOUT constant bounds
504 if (! mode_is_float(get_irn_mode(left)) &&
505 (pnc == pn_Cmp_Eq || pnc == pn_Cmp_Lg)) {
506 /* l == r if bound(l) == bound(r) AND pnc(l) == pnc(r) == '=' */
507 if (r_bound == l_bound && r_pnc == l_pnc && r_pnc == pn_Cmp_Eq) {
508 DBG_EVAL_CONFIRM(cmp);
509 return pnc == pn_Cmp_Eq ? tarval_b_true : tarval_b_false;
513 * Here, we check only the right Confirm, as the left Confirms are
514 * checked later anyway.
517 if (left == r_bound && (r_pnc == pn_Cmp_Eq || r_pnc == pn_Cmp_Lg)) {
518 /* l == bound(r) AND pnc(r) == pnc */
520 DBG_EVAL_CONFIRM(cmp);
521 return tarval_b_true;
523 /* l == bound(r) AND pnc(r) != pnc */
525 DBG_EVAL_CONFIRM(cmp);
526 return tarval_b_false;
531 /* now, try interval magic */
533 get_interval(&l_iv, l_bound, l_pnc),
534 get_interval(&r_iv, r_bound, r_pnc),
537 if (tv != tarval_bad) {
538 DBG_EVAL_CONFIRM(cmp);
543 /* from Here, check only left Confirm */
546 * checks for == or != can sometime be made WITHOUT constant bounds
549 if (! mode_is_float(get_irn_mode(left)) &&
550 (pnc == pn_Cmp_Eq || pnc == pn_Cmp_Lg)) {
551 if (right == l_bound && (l_pnc == pn_Cmp_Eq || l_pnc == pn_Cmp_Lg)) {
552 /* r == bound(l) AND pnc(l) == pnc */
554 DBG_EVAL_CONFIRM(cmp);
555 return tarval_b_true;
557 /* r == bound(l) AND pnc(l) != pnc */
559 DBG_EVAL_CONFIRM(cmp);
560 return tarval_b_false;
565 /* now, only right == Const can help */
566 tv = value_of(right);
568 if (tv != tarval_bad) {
570 get_interval(&l_iv, l_bound, l_pnc),
571 get_interval_from_tv(&r_iv, tv),
575 if (tv != tarval_bad)
576 DBG_EVAL_CONFIRM(cmp);