X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Flower%2Flower_mode_b.c;h=f698441d824c4b6ab887d9996e4a1a226d1d5706;hb=8057f671ea7f286a27e40bfe1aa45d85e0990cbe;hp=d6274472bc726087dc0970a4a31a648ce9d3cddc;hpb=4b295e5bec7e358e114e2585b1d16f33a11559a0;p=libfirm diff --git a/ir/lower/lower_mode_b.c b/ir/lower/lower_mode_b.c index d6274472b..f698441d8 100644 --- a/ir/lower/lower_mode_b.c +++ b/ir/lower/lower_mode_b.c @@ -21,7 +21,6 @@ * @file * @brief lower mode_b operations to something the backend can handle * @author Matthias Braun, Christoph Mallon - * @version $Id$ */ #include "config.h" @@ -45,19 +44,20 @@ #include "irpass_t.h" #include "util.h" #include "array.h" +#include "irgopt.h" typedef struct needs_lowering_t { ir_node *node; int input; } needs_lowering_t; -static const lower_mode_b_config_t *config; -static needs_lowering_t *needs_lowering; +static ir_mode *lowered_mode; +static needs_lowering_t *needs_lowering; static ir_node *create_not(dbg_info *dbgi, ir_node *node) { ir_node *block = get_nodes_block(node); - ir_mode *mode = config->lowered_mode; + ir_mode *mode = lowered_mode; ir_tarval *tv_one = get_mode_one(mode); ir_graph *irg = get_irn_irg(node); ir_node *one = new_rd_Const(dbgi, irg, tv_one); @@ -69,14 +69,18 @@ static ir_node *convert_to_modeb(ir_node *node) { ir_node *block = get_nodes_block(node); ir_graph *irg = get_irn_irg(node); - ir_mode *mode = config->lowered_mode; + ir_mode *mode = lowered_mode; ir_tarval *tv_zero = get_mode_null(mode); ir_node *zero = new_r_Const(irg, tv_zero); ir_node *cmp = new_r_Cmp(block, node, zero, ir_relation_less_greater); return cmp; } -ir_node *ir_create_cond_set(ir_node *cond_value, ir_mode *dest_mode) +/** + * implementation of create_set_func which produces a cond with control + * flow + */ +static ir_node *create_cond_set(ir_node *cond_value, ir_mode *dest_mode) { ir_node *lower_block = part_block_edges(cond_value); ir_node *upper_block = get_nodes_block(cond_value); @@ -106,7 +110,7 @@ static ir_node *lower_node(ir_node *node) { dbg_info *dbgi = get_irn_dbg_info(node); ir_node *block = get_nodes_block(node); - ir_mode *mode = config->lowered_mode; + ir_mode *mode = lowered_mode; ir_node *res = (ir_node*)get_irn_link(node); ir_graph *irg; @@ -190,65 +194,9 @@ static ir_node *lower_node(ir_node *node) break; } - case iro_Cmp: { - ir_node *left = get_Cmp_left(node); - ir_node *right = get_Cmp_right(node); - ir_mode *cmp_mode = get_irn_mode(left); - ir_relation relation = get_Cmp_relation(node); - - if ((mode_is_int(cmp_mode) || mode_is_reference(cmp_mode)) && - (get_mode_size_bits(cmp_mode) < get_mode_size_bits(mode) || - (mode_is_signed(cmp_mode) && is_Const(right) && is_Const_null(right) && relation != ir_relation_greater))) { - int need_not = 0; - ir_node *a = NULL; - ir_node *b = NULL; - int bits; - ir_tarval *tv; - ir_node *shift_cnt; - - if (relation == ir_relation_less) { - /* a < b -> (a - b) >> 31 */ - a = left; - b = right; - } else if (relation == ir_relation_less_equal) { - /* a <= b -> ~(a - b) >> 31 */ - a = right; - b = left; - need_not = 1; - } else if (relation == ir_relation_greater) { - /* a > b -> (b - a) >> 31 */ - a = right; - b = left; - } else if (relation == ir_relation_greater_equal) { - /* a >= b -> ~(a - b) >> 31 */ - a = left; - b = right; - need_not = 1; - } else { - goto synth_zero_one; - } - - bits = get_mode_size_bits(mode); - tv = new_tarval_from_long(bits-1, mode_Iu); - shift_cnt = new_rd_Const(dbgi, irg, tv); - - if (cmp_mode != mode) { - a = new_rd_Conv(dbgi, block, a, mode); - b = new_rd_Conv(dbgi, block, b, mode); - } - - res = new_rd_Sub(dbgi, block, a, b, mode); - if (need_not) { - res = new_rd_Not(dbgi, block, res, mode); - } - res = new_rd_Shr(dbgi, block, res, shift_cnt, mode); - } else { - /* synthesize the 0/1 value */ -synth_zero_one: - res = config->create_set(node); - } + case iro_Cmp: + res = create_cond_set(node, mode); break; - } case iro_Const: { ir_tarval *tv = get_Const_tarval(node); @@ -288,7 +236,7 @@ static bool needs_mode_b_input(const ir_node *node, int input) /** * Collects "roots" of a mode_b calculation. These are nodes which require a - * mode_b input (Cond, Mux, Conv(xxx_b)) + * mode_b input (Cond, Mux) */ static void collect_needs_lowering(ir_node *node, void *env) { @@ -296,7 +244,7 @@ static void collect_needs_lowering(ir_node *node, void *env) int i; (void) env; - /* if the node produces mode_b then it is a not a root (but should be + /* if the node produces mode_b then it is not a root (but should be * something our lower_node function can handle) */ if (get_irn_mode(node) == mode_b) { assert(is_And(node) || is_Or(node) || is_Eor(node) || is_Phi(node) @@ -319,17 +267,19 @@ static void collect_needs_lowering(ir_node *node, void *env) } } -void ir_lower_mode_b(ir_graph *irg, const lower_mode_b_config_t *nconfig) +void ir_lower_mode_b(ir_graph *const irg, ir_mode *const nlowered_mode) { size_t i; size_t n; - config = nconfig; + lowered_mode = nlowered_mode; /* edges are used by part_block_edges in the ir_create_cond_set variant. */ - edges_assure(irg); + assure_edges(irg); + /* part_block_edges can go wrong with tuples present */ + remove_tuples(irg); - set_irg_state(irg, IR_GRAPH_STATE_MODEB_LOWERED); + add_irg_constraints(irg, IR_GRAPH_CONSTRAINT_MODEB_LOWERED); ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK); needs_lowering = NEW_ARR_F(needs_lowering_t, 0); @@ -355,8 +305,7 @@ void ir_lower_mode_b(ir_graph *irg, const lower_mode_b_config_t *nconfig) if (n > 0) { /* lowering might create new blocks, so be sure to handle this */ - clear_irg_state(irg, IR_GRAPH_STATE_CONSISTENT_DOMINANCE - | IR_GRAPH_STATE_VALID_EXTENDED_BLOCKS); + clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE); edges_deactivate(irg); } }