X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Fopt_confirms.c;h=ee23ee53a01a1de0c3824fa136bcd20b87e8a146;hb=153ed01cac8be211f278b6b7c319681c12a97c54;hp=8a9baa479d2dc13ec2f82a05dc6ecd3d8e277458;hpb=7ca3ea53a92e084499a439f299d224efdaae6546;p=libfirm diff --git a/ir/opt/opt_confirms.c b/ir/opt/opt_confirms.c index 8a9baa479..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 { @@ -76,7 +77,7 @@ static tarval *compare_iv_dbg(const interval_t *l_iv, const interval_t *r_iv, pn #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 @@ -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: @@ -758,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 */