* This is a often needed case, so we handle here Confirm
* nodes too.
*/
-int value_not_zero(ir_node *n)
+int value_not_zero(ir_node *n, ir_node **confirm)
{
-#define RET_ON(x) if (x) return 1; break
+#define RET_ON(x) if (x) { *confirm = n; return 1; }; break
tarval *tv;
ir_mode *mode = get_irn_mode(n);
pn_Cmp pnc;
+ *confirm = NULL;
while (get_irn_op(n) == op_Confirm) {
/*
* Note: A Confirm is never after a Const. So,
if (tv == tarval_bad)
return 0;
- pnc = tarval_cmp(tv, get_mode_null(mode));
+ pnc = tarval_cmp(tv, get_mode_null(mode));
/*
* Beware: C might by a NaN. It is not clear, what we should do
return (pnc != pn_Cmp_Eq) && (pnc != pn_Cmp_Uo);
#undef RET_ON
-}
+} /* value_not_zero */
/*
* Check, if the value of a node cannot represent a NULL pointer.
* - A SymConst(entity) is NEVER a NULL pointer
* - Confirms are evaluated
*/
-int value_not_null(ir_node *n)
+int value_not_null(ir_node *n, ir_node **confirm)
{
ir_op *op;
+ *confirm = NULL;
n = skip_Cast(n);
op = get_irn_op(n);
assert(mode_is_reference(get_irn_mode(n)));
}
if (op == op_SymConst && get_SymConst_kind(n) == symconst_addr_ent)
return 1;
- if (op == op_Confirm) {
+ if (op == op_Const) {
+ tarval *tv = get_Const_tarval(n);
+
+ if (tv != tarval_bad && classify_tarval(tv) != TV_CLASSIFY_NULL)
+ return 1;
+ }
+ else if (op == op_Confirm) {
if (get_Confirm_cmp(n) == pn_Cmp_Lg &&
- classify_Const(get_Confirm_bound(n)) == CNST_NULL)
+ classify_Const(get_Confirm_bound(n)) == CNST_NULL) {
+ *confirm = n;
return 1;
+ }
}
return 0;
-}
+} /* value_not_null */
/*
* Check, if the value of a node can be confirmed >= 0 or <= 0,
* If the mode of the value did not honor signed zeros, else
* check for >= 0 or < 0.
*/
-value_classify classify_value_sign(ir_node *n)
+value_classify_sign classify_value_sign(ir_node *n)
{
tarval *tv, *c;
ir_mode *mode;
pn_Cmp cmp, ncmp;
if (get_irn_op(n) != op_Confirm)
- return VALUE_UNKNOWN;
+ return value_classified_unknown;
tv = value_of(get_Confirm_bound(n));
if (tv == tarval_bad)
- return VALUE_UNKNOWN;
+ return value_classified_unknown;
mode = get_irn_mode(n);
ncmp = pn_Cmp_Le;
if (cmp != (ncmp ^ pn_Cmp_Eq))
- return VALUE_UNKNOWN;
+ return value_classified_unknown;
/* yep, negative */
- return VALUE_NEGATIVE;
+ return value_classified_negative;
case pn_Cmp_Ge:
/*
ncmp = pn_Cmp_Ge;
if (cmp != (ncmp ^ pn_Cmp_Eq))
- return VALUE_UNKNOWN;
+ return value_classified_unknown;
}
else {
c = get_mode_minus_one(mode);
ncmp = tarval_cmp(tv, c);
if (ncmp != pn_Cmp_Eq && ncmp != pn_Cmp_Gt)
- return VALUE_UNKNOWN;
+ return value_classified_unknown;
}
/* yep, positive */
- return VALUE_POSITIVE;
+ return value_classified_positive;
default:
- return VALUE_UNKNOWN;
+ return value_classified_unknown;
}
-}
+} /* classify_value_sign */
/**
* construct an interval from a value
iv->flags = MIN_INCLUDED | MAX_INCLUDED;
return iv;
-}
+} /* get_interval_from_tv */
/**
* construct an interval from a Confirm
if (iv->min != tarval_bad && iv->max != tarval_bad)
return iv;
return NULL;
-}
+} /* get_interval */
/**
* Try to evaluate l_iv pnc r_iv.
return tarval_bad;
}
return tarval_bad;
-}
+} /* compare_iv */
/**
* Returns non-zero, if a given relation is transitive.
*/
static int is_transitive(pn_Cmp pnc) {
return (pn_Cmp_False < pnc && pnc < pn_Cmp_Lg);
-}
+} /* is_transitive */
/**
DBG_EVAL_CONFIRM(cmp);
return tv;
-}
+} /* computed_value_Cmp_Confirm */
#ifdef DEBUG_CONFIRM
/**
return snprintf(buf, len, "%s", smin);
}
return snprintf(buf, len, "<UNKNOWN>");
-}
+} /* iv_snprintf */
/**
* For debugging. Prints an interval compare.
iv_snprintf(sr, sizeof(sr), r_iv);
ir_printf("%s %= %s", sl, pnc, sr);
-}
+} /* print_iv_cmp */
/**
* For debugging. call *compare_iv() and prints inputs and result.
print_iv_cmp(l_iv, r_iv, pnc);
ir_printf(" = %T\n", tv);
return tv;
-}
+} /* compare_iv_dbg */
#endif /* DEBUG_CONFIRM */
* Created:
* CVS-ID: $Id$
* Copyright: (c) 1998-2005 Universität Karlsruhe
- * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
+ * License: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
*/
#ifndef _OPT_CONFIRMS_H_
#define _OPT_CONFIRMS_H_
#include "irnode.h"
-/**
+/**a
* @file opt_confirms.h
*
* Optimizations regarding Confirm nodes.
- * These optimiztions are not means to be run from
+ * These optimizations are not means to be run from
* frontends, they are called from iropt.
*/
-/**
- * Possible return values of value_classify().
- */
-typedef enum _value_classify {
- VALUE_UNKNOWN = 0, /**< could not classify */
- VALUE_POSITIVE = 1, /**< value is positive, i.e. >= 0 */
- VALUE_NEGATIVE = -1 /**< value is negative, i.e. <= 0 if
- no signed zero exists or < 0 else */
-} value_classify;
-
/**
* Check, if the value of a node is != 0.
*
* This is a often needed case, so we handle here Confirm
* nodes too.
*
- * @param n a node representing the value
+ * @param n a node representing the value
+ * @param confirm if n is confirmed to be != 0, returns
+ * the the Confirm-node, else NULL
*/
-int value_not_zero(ir_node *n);
+int value_not_zero(ir_node *n, ir_node **confirm);
/**
* Check, if the value of a node cannot represent a NULL pointer.
* - If sel_based_null_check_elim is enabled, all
* Sel nodes can be skipped.
* - A SymConst(entity) is NEVER a NULL pointer
+ * - A Const != NULL is NEVER a NULL pointer
* - Confirms are evaluated
*
- * @param n a node representing the value
+ * @param n a node representing the value
+ * @param confirm if n is confirmed to be != NULL, returns
+ * the the Confirm-node, else NULL
+ */
+int value_not_null(ir_node *n, ir_node **confirm);
+
+/**
+ * Possible return values of value_classify().
*/
-int value_not_null(ir_node *n);
+typedef enum _value_classify_sign {
+ value_classified_unknown = 0, /**< could not classify */
+ value_classified_positive = 1, /**< value is positive, i.e. >= 0 */
+ value_classified_negative = -1 /**< value is negative, i.e. <= 0 if
+ no signed zero exists or < 0 else */
+} value_classify_sign;
/**
* Check, if the value of a node can be confirmed >= 0 or <= 0,
*
* @param n a node representing the value
*/
-value_classify classify_value_sign(ir_node *n);
+value_classify_sign classify_value_sign(ir_node *n);
/**
* Return the value of a Cmp if one or both predecessors