#include "iropt_t.h"
#include "iropt_dbg.h"
#include "opt_confirms.h"
+#include "irflag_t.h"
#include "irprintf.h"
enum range_tags {
#define DBG_OUT_R(r_pnc, r_bound, left, pnc, right, v)
#define DBG_OUT_L(l_pnc, l_bound, left, pnc, right, v)
-#endif
+#endif /* DEBUG_CONFIRM */
-/**
+/*
* Check, if the value of a node is != 0.
*
* This is a often needed case, so we handle here Confirm
while (get_irn_op(n) == op_Confirm) {
/*
* Note: A Confirm is never after a Const. So,
- * we simply can check the bound for beeing a Const
+ * we simply can check the bound for being a Const
* without the fear that is might be hidden by a further Confirm.
*/
tv = value_of(get_Confirm_bound(n));
#undef RET_ON
}
+/*
+ * Check, if the value of a node cannot represent a NULL pointer.
+ *
+ * - Casts are skipped
+ * - If sel_based_null_check_elim is enabled, all
+ * Sel nodes can be skipped.
+ * - A SymConst(entity) is NEVER a NULL pointer
+ * - Confirms are evaluated
+ */
+int value_not_null(ir_node *n)
+{
+ ir_op *op;
+
+ n = skip_Cast(n);
+ op = get_irn_op(n);
+ assert(mode_is_reference(get_irn_mode(n)));
+ if (get_opt_sel_based_null_check_elim()) {
+ /* skip all Sel nodes and Cast's */
+ while (op == op_Sel) {
+ n = skip_Cast(get_Sel_ptr(n));
+ op = get_irn_op(n);
+ }
+ }
+ if (op == op_SymConst && get_SymConst_kind(n) == symconst_addr_ent)
+ return 1;
+ if (op == op_Confirm) {
+ if (get_Confirm_cmp(n) == pn_Cmp_Lg &&
+ classify_Const(get_Confirm_bound(n)) == CNST_NULL)
+ return 1;
+ }
+ return 0;
+}
+
/*
* 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
*
* @param iv an empty interval, will be filled
* @param bound the bound value
- * @param pnc the Confirm pnc relation
+ * @param pnc the Confirm compare relation
*
* @return the filled interval or NULL if no interval
* can be created (happens only on floating point
if (l_iv->min == l_iv->max && r_iv->min == r_iv->max)
return tarval_cmp(l_iv->min, r_iv->min) == pn_Cmp_Eq ? tv_true : tv_false;
- /* if both interval do not intersect, it is never equal */
+ /* if both intervals do not intersect, it is never equal */
res = tarval_cmp(l_iv->max, r_iv->min);
/* b < c ==> [a,b] != [c,d] */
if (res == pn_Cmp_Lt)
- return tv_false;
+ return tv_false;
/* b <= c ==> [a,b) != [c,d] AND [a,b] != (c,d] */
if ((l_iv->flags & MAX_EXCLUDED || r_iv->flags & MIN_EXCLUDED)
- && (res == pn_Cmp_Eq))
- return tv_false;
+ && (res == pn_Cmp_Eq))
+ return tv_false;
res = tarval_cmp(r_iv->max, l_iv->min);
/* d < a ==> [c,d] != [a,b] */
if (res == pn_Cmp_Lt)
- return tv_false;
+ return tv_false;
/* d <= a ==> [c,d) != [a,b] AND [c,d] != (a,b] */
if ((r_iv->flags & MAX_EXCLUDED || l_iv->flags & MIN_EXCLUDED)
- && (res == pn_Cmp_Eq))
- return tv_false;
+ && (res == pn_Cmp_Eq))
+ return tv_false;
break;
case pn_Cmp_Lg:
* Return the value of a Cmp if one or both predecessors
* are Confirm nodes.
*
+ * @param cmp the Cmp node
* @param left the left operand of the Cmp
* @param right the right operand of the Cmp
+ * @param pnc the compare relation
*/
tarval *computed_value_Cmp_Confirm(ir_node *cmp, ir_node *left, ir_node *right, pn_Cmp pnc)
{
return tv;
}
+#ifdef DEBUG_CONFIRM
/**
* For debugging. Prints an interval into a string.
+ *
+ * @param buf address of a string buffer
+ * @param len length of the string buffer
+ * @param iv the interval
*/
static int iv_snprintf(char *buf, size_t len, const interval_t *iv) {
char smin[64], smax[64];
return snprintf(buf, len, "<UNKNOWN>");
}
-#ifdef DEBUG_CONFIRM
/**
- * For debugging. Prints an interval compare
+ * For debugging. Prints an interval compare.
+ *
+ * @param l_iv the left interval
+ * @param r_iv the right interval
+ * @param pnc the compare relation
*/
static void print_iv_cmp(const interval_t *l_iv, const interval_t *r_iv, pn_Cmp pnc)
{
}
/**
- * For debugging. call *compare_iv() and prints inputs and result
+ * For debugging. call *compare_iv() and prints inputs and result.
+ *
+ * @param l_iv the left interval
+ * @param r_iv the right interval
+ * @param pnc the compare relation
*/
static tarval *compare_iv_dbg(const interval_t *l_iv, const interval_t *r_iv, pn_Cmp pnc)
{
ir_printf("In %e:\n", get_irg_entity(current_ir_graph));
print_iv_cmp(l_iv, r_iv, pnc);
ir_printf(" = %T\n", tv);
- return tv;
+ return tv;
}
#endif /* DEBUG_CONFIRM */