X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Fopt_confirms.c;h=ee23ee53a01a1de0c3824fa136bcd20b87e8a146;hb=153ed01cac8be211f278b6b7c319681c12a97c54;hp=f005c273f14602088d899362cdc61dc9a2a35958;hpb=b83b5acde66b0564b261d05724e03084bf2f0c25;p=libfirm diff --git a/ir/opt/opt_confirms.c b/ir/opt/opt_confirms.c index f005c273f..ee23ee53a 100644 --- a/ir/opt/opt_confirms.c +++ b/ir/opt/opt_confirms.c @@ -20,6 +20,7 @@ #include "iropt_t.h" #include "iropt_dbg.h" #include "opt_confirms.h" +#include "irflag_t.h" #include "irprintf.h" enum range_tags { @@ -74,9 +75,9 @@ static tarval *compare_iv_dbg(const interval_t *l_iv, const interval_t *r_iv, pn #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 @@ -93,7 +94,7 @@ int value_not_zero(ir_node *n) 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)); @@ -143,6 +144,39 @@ int value_not_zero(ir_node *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 @@ -285,7 +319,7 @@ static interval_t *get_interval_from_tv(interval_t *iv, tarval *tv) * * @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 @@ -430,28 +464,28 @@ static tarval *(compare_iv)(const interval_t *l_iv, const interval_t *r_iv, pn_C 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: @@ -527,8 +561,10 @@ static int is_transitive(pn_Cmp pnc) { * 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) { @@ -693,8 +729,13 @@ tarval *computed_value_Cmp_Confirm(ir_node *cmp, ir_node *left, ir_node *right, 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]; @@ -717,9 +758,12 @@ static int iv_snprintf(char *buf, size_t len, const interval_t *iv) { return snprintf(buf, len, ""); } -#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) { @@ -732,7 +776,11 @@ static void print_iv_cmp(const interval_t *l_iv, const interval_t *r_iv, pn_Cmp } /** - * 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) { @@ -744,7 +792,7 @@ static tarval *compare_iv_dbg(const interval_t *l_iv, const interval_t *r_iv, pn 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 */