X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Ffp-vrp.c;h=a3c6abfd9ff789ae377b38afc5e6a69e3d69f955;hb=b42d141b27222454d6176f233327c594d71be554;hp=777632350d5221f370dd1729aebf144c4a5a12a7;hpb=9d3c8631459f431c313160dab5778e8a7b88dd92;p=libfirm diff --git a/ir/opt/fp-vrp.c b/ir/opt/fp-vrp.c index 777632350..a3c6abfd9 100644 --- a/ir/opt/fp-vrp.c +++ b/ir/opt/fp-vrp.c @@ -133,7 +133,7 @@ typedef struct environment_t { static inline bitinfo* get_bitinfo(ir_node const* const irn) { - return get_irn_link(irn); + return (bitinfo*)get_irn_link(irn); } static int set_bitinfo(ir_node* const irn, ir_tarval* const z, ir_tarval* const o) @@ -470,45 +470,78 @@ result_unknown_X: if (is_Cmp(pred)) { // TODO generalize bitinfo* const l = get_bitinfo(get_Cmp_left(pred)); bitinfo* const r = get_bitinfo(get_Cmp_right(pred)); - if (l == NULL || r == NULL) + if (l == NULL || r == NULL) { goto result_unknown; // Cmp compares something we cannot evaluate. - switch (get_Proj_proj(irn)) { - case pn_Cmp_Lg: { - ir_tarval* const lz = l->z; - ir_tarval* const lo = l->o; - ir_tarval* const rz = r->z; - ir_tarval* const ro = r->o; - if (!tarval_is_null(tarval_andnot(ro, lz)) || - !tarval_is_null(tarval_andnot(lo, rz))) { - // At least one bit differs. - z = o = get_tarval_b_true(); - } else if (lz == lo && rz == ro && lz == rz) { - z = o = get_tarval_b_false(); - } else { - goto result_unknown; - } - break; - } - - case pn_Cmp_Eq: { - ir_tarval* const lz = l->z; - ir_tarval* const lo = l->o; - ir_tarval* const rz = r->z; - ir_tarval* const ro = r->o; - if (!tarval_is_null(tarval_andnot(ro, lz)) || - !tarval_is_null(tarval_andnot(lo, rz))) { - // At least one bit differs. - z = o = get_tarval_b_false(); - } else if (lz == lo && rz == ro && lz == rz) { - z = o = get_tarval_b_true(); - } else { - goto result_unknown; - } - break; + } else { + ir_tarval* const lz = l->z; + ir_tarval* const lo = l->o; + ir_tarval* const rz = r->z; + ir_tarval* const ro = r->o; + pn_Cmp const pn = get_Proj_proj(irn); + switch (pn) { + case pn_Cmp_Lg: + if (!tarval_is_null(tarval_andnot(ro, lz)) || + !tarval_is_null(tarval_andnot(lo, rz))) { + // At least one bit differs. + z = o = get_tarval_b_true(); + } else if (lz == lo && rz == ro && lz == rz) { + z = o = get_tarval_b_false(); + } else { + goto result_unknown; + } + break; + + case pn_Cmp_Eq: + if (!tarval_is_null(tarval_andnot(ro, lz)) || + !tarval_is_null(tarval_andnot(lo, rz))) { + // At least one bit differs. + z = o = get_tarval_b_false(); + } else if (lz == lo && rz == ro && lz == rz) { + z = o = get_tarval_b_true(); + } else { + goto result_unknown; + } + break; + + case pn_Cmp_Le: + case pn_Cmp_Lt: + /* TODO handle negative values */ + if (tarval_is_negative(lz) || tarval_is_negative(lo) || + tarval_is_negative(rz) || tarval_is_negative(ro)) + goto result_unknown; + + if (tarval_cmp(lz, ro) & pn) { + /* Left upper bound is smaller(/equal) than right lower bound. */ + z = o = get_tarval_b_true(); + } else if (!(tarval_cmp(lo, rz) & pn)) { + /* Left lower bound is not smaller(/equal) than right upper bound. */ + z = o = get_tarval_b_false(); + } else { + goto result_unknown; + } + break; + + case pn_Cmp_Ge: + case pn_Cmp_Gt: + /* TODO handle negative values */ + if (tarval_is_negative(lz) || tarval_is_negative(lo) || + tarval_is_negative(rz) || tarval_is_negative(ro)) + goto result_unknown; + + if (!(tarval_cmp(lz, ro) & pn)) { + /* Left upper bound is not greater(/equal) than right lower bound. */ + z = o = get_tarval_b_false(); + } else if (tarval_cmp(lo, rz) & pn) { + /* Left lower bound is greater(/equal) than right upper bound. */ + z = o = get_tarval_b_true(); + } else { + goto result_unknown; + } + break; + + default: + goto cannot_analyse; } - - default: - goto cannot_analyse; } } else { goto cannot_analyse; @@ -534,7 +567,7 @@ result_unknown: static void first_round(ir_node* const irn, void* const env) { - pdeq* const q = env; + pdeq* const q = (pdeq*)env; transfer(irn); if (is_Phi(irn) || is_Block(irn)) { @@ -548,10 +581,10 @@ static void first_round(ir_node* const irn, void* const env) static void apply_result(ir_node* const irn, void* ctx) { - bitinfo* const b = get_bitinfo(irn); + environment_t* env = (environment_t*)ctx; + bitinfo* const b = get_bitinfo(irn); ir_tarval* z; ir_tarval* o; - environment_t* env = ctx; if (!b) return; if (is_Const(irn)) return; // It cannot get any better than a Const. @@ -707,7 +740,7 @@ void fixpoint_vrp(ir_graph* const irg) irg_walk_blkwise_dom_top_down(irg, firm_clear_link, first_round, q); while (!pdeq_empty(q)) { - ir_node* const n = pdeq_getl(q); + ir_node* const n = (ir_node*)pdeq_getl(q); if (transfer(n)) queue_users(q, n); }