Commit 77c35e4a authored by Christoph Mallon's avatar Christoph Mallon
Browse files

When making a 'Mux', automatically infer its mode from its 'false' operand.

parent 7715d51a
...@@ -1949,6 +1949,8 @@ static void fixup_phi(ir_node *phi) ...@@ -1949,6 +1949,8 @@ static void fixup_phi(ir_node *phi)
*/ */
static void lower_Mux(ir_node *mux, ir_mode *mode) static void lower_Mux(ir_node *mux, ir_mode *mode)
{ {
(void)mode;
ir_node *truen = get_Mux_true(mux); ir_node *truen = get_Mux_true(mux);
ir_node *falsen = get_Mux_false(mux); ir_node *falsen = get_Mux_false(mux);
ir_node *sel = get_Mux_sel(mux); ir_node *sel = get_Mux_sel(mux);
...@@ -1960,10 +1962,8 @@ static void lower_Mux(ir_node *mux, ir_mode *mode) ...@@ -1960,10 +1962,8 @@ static void lower_Mux(ir_node *mux, ir_mode *mode)
ir_node *false_h = false_entry->high_word; ir_node *false_h = false_entry->high_word;
dbg_info *dbgi = get_irn_dbg_info(mux); dbg_info *dbgi = get_irn_dbg_info(mux);
ir_node *block = get_nodes_block(mux); ir_node *block = get_nodes_block(mux);
ir_node *res_low ir_node *res_low = new_rd_Mux(dbgi, block, sel, false_l, true_l);
= new_rd_Mux(dbgi, block, sel, false_l, true_l, env.p.word_unsigned); ir_node *res_high = new_rd_Mux(dbgi, block, sel, false_h, true_h);
ir_node *res_high
= new_rd_Mux(dbgi, block, sel, false_h, true_h, mode);
ir_set_dw_lowered(mux, res_low, res_high); ir_set_dw_lowered(mux, res_low, res_high);
} }
...@@ -2277,11 +2277,11 @@ static void lower_reduce_builtin(ir_node *builtin, ir_mode *mode) ...@@ -2277,11 +2277,11 @@ static void lower_reduce_builtin(ir_node *builtin, ir_mode *mode)
ir_node *high = new_rd_Add(dbgi, block, high_proj, number_of_bits, result_mode); ir_node *high = new_rd_Add(dbgi, block, high_proj, number_of_bits, result_mode);
ir_node *ffs_low = new_rd_Builtin(dbgi, block, mem, 1, in_low, kind, lowered_type_low); ir_node *ffs_low = new_rd_Builtin(dbgi, block, mem, 1, in_low, kind, lowered_type_low);
ir_node *low = new_r_Proj(ffs_low, result_mode, pn_Builtin_max+1); ir_node *low = new_r_Proj(ffs_low, result_mode, pn_Builtin_max+1);
ir_node *mux_high = new_rd_Mux(dbgi, block, cmp_high, high, zero_result, result_mode); ir_node *mux_high = new_rd_Mux(dbgi, block, cmp_high, high, zero_result);
if (!allow_ifconv(cmp_high, high, zero_result)) if (!allow_ifconv(cmp_high, high, zero_result))
ir_nodeset_insert(&created_mux_nodes, mux_high); ir_nodeset_insert(&created_mux_nodes, mux_high);
res = new_rd_Mux(dbgi, block, cmp_low, low, mux_high, result_mode); res = new_rd_Mux(dbgi, block, cmp_low, low, mux_high);
if (!allow_ifconv(cmp_low, low, mux_high)) if (!allow_ifconv(cmp_low, low, mux_high))
ir_nodeset_insert(&created_mux_nodes, res); ir_nodeset_insert(&created_mux_nodes, res);
...@@ -2296,7 +2296,7 @@ static void lower_reduce_builtin(ir_node *builtin, ir_mode *mode) ...@@ -2296,7 +2296,7 @@ static void lower_reduce_builtin(ir_node *builtin, ir_mode *mode)
ir_node *low_proj = new_r_Proj(clz_low, result_mode, pn_Builtin_max+1); ir_node *low_proj = new_r_Proj(clz_low, result_mode, pn_Builtin_max+1);
ir_node *number_of_bits = new_r_Const_long(irg, result_mode, get_mode_size_bits(mode)); ir_node *number_of_bits = new_r_Const_long(irg, result_mode, get_mode_size_bits(mode));
ir_node *low = new_rd_Add(dbgi, block, low_proj, number_of_bits, result_mode); ir_node *low = new_rd_Add(dbgi, block, low_proj, number_of_bits, result_mode);
res = new_rd_Mux(dbgi, block, cmp_high, high, low, result_mode); res = new_rd_Mux(dbgi, block, cmp_high, high, low);
if (!allow_ifconv(cmp_high, high, low)) if (!allow_ifconv(cmp_high, high, low))
ir_nodeset_insert(&created_mux_nodes, res); ir_nodeset_insert(&created_mux_nodes, res);
...@@ -2311,7 +2311,7 @@ static void lower_reduce_builtin(ir_node *builtin, ir_mode *mode) ...@@ -2311,7 +2311,7 @@ static void lower_reduce_builtin(ir_node *builtin, ir_mode *mode)
ir_node *high = new_rd_Add(dbgi, block, high_proj, number_of_bits, result_mode); ir_node *high = new_rd_Add(dbgi, block, high_proj, number_of_bits, result_mode);
ir_node *ffs_low = new_rd_Builtin(dbgi, block, mem, 1, in_low, kind, lowered_type_low); ir_node *ffs_low = new_rd_Builtin(dbgi, block, mem, 1, in_low, kind, lowered_type_low);
ir_node *low = new_r_Proj(ffs_low, result_mode, pn_Builtin_max+1); ir_node *low = new_r_Proj(ffs_low, result_mode, pn_Builtin_max+1);
res = new_rd_Mux(dbgi, block, cmp_low, low, high, result_mode); res = new_rd_Mux(dbgi, block, cmp_low, low, high);
if (!allow_ifconv(cmp_low, low, high)) if (!allow_ifconv(cmp_low, low, high))
ir_nodeset_insert(&created_mux_nodes, res); ir_nodeset_insert(&created_mux_nodes, res);
......
...@@ -182,7 +182,7 @@ int i_mapper_abs(ir_node *call) ...@@ -182,7 +182,7 @@ int i_mapper_abs(ir_node *call)
return 0; return 0;
/* construct Mux */ /* construct Mux */
mux = new_rd_Mux(dbg, block, cmp, op, minus_op, mode); mux = new_rd_Mux(dbg, block, cmp, op, minus_op);
DBG_OPT_ALGSIM0(call, mux); DBG_OPT_ALGSIM0(call, mux);
replace_call(mux, call, mem, NULL, NULL); replace_call(mux, call, mem, NULL, NULL);
return 1; return 1;
......
...@@ -517,7 +517,7 @@ static bool lower_Cmp(ir_node *const n) ...@@ -517,7 +517,7 @@ static bool lower_Cmp(ir_node *const n)
result = make_softfloat_call(n, name2, ARRAY_SIZE(in), in); result = make_softfloat_call(n, name2, ARRAY_SIZE(in), in);
relation = get_Cmp_relation(n); relation = get_Cmp_relation(n);
ir_node *const mux = new_rd_Mux(dbgi, block, cmp, result, zero, mode_Is); ir_node *const mux = new_rd_Mux(dbgi, block, cmp, result, zero);
arch_allow_ifconv_func const allow_ifconv arch_allow_ifconv_func const allow_ifconv
= be_get_backend_param()->allow_ifconv; = be_get_backend_param()->allow_ifconv;
......
...@@ -351,7 +351,7 @@ restart:; ...@@ -351,7 +351,7 @@ restart:;
} }
dbg_info *const dbgi = get_irn_dbg_info(phi); dbg_info *const dbgi = get_irn_dbg_info(phi);
mux = new_rd_Mux(dbgi, mux_block, sel, f, t, get_irn_mode(phi)); mux = new_rd_Mux(dbgi, mux_block, sel, f, t);
DB((dbg, LEVEL_2, "Generating %+F for %+F\n", mux, phi)); DB((dbg, LEVEL_2, "Generating %+F for %+F\n", mux, phi));
} }
......
...@@ -1931,13 +1931,11 @@ static ir_node *apply_conv_on_phi(ir_node *phi, ir_mode *mode) ...@@ -1931,13 +1931,11 @@ static ir_node *apply_conv_on_phi(ir_node *phi, ir_mode *mode)
* @param mux the Mux node * @param mux the Mux node
* @param other the other operand * @param other the other operand
* @param eval an evaluator function * @param eval an evaluator function
* @param mode the mode of the result, may be different from the mode of the Mux!
* @param left if true, other is the left operand, else the right * @param left if true, other is the left operand, else the right
* *
* @return a new Mux node if the conversion was successful, NULL else * @return a new Mux node if the conversion was successful, NULL else
*/ */
static ir_node *apply_binop_on_mux(ir_node *mux, ir_tarval *other, static ir_node *apply_binop_on_mux(ir_node *mux, ir_tarval *other, tarval_binop eval, bool left)
tarval_binop eval, ir_mode *mode, bool left)
{ {
if (!only_one_user(mux)) if (!only_one_user(mux))
return NULL; return NULL;
...@@ -1962,7 +1960,7 @@ static ir_node *apply_binop_on_mux(ir_node *mux, ir_tarval *other, ...@@ -1962,7 +1960,7 @@ static ir_node *apply_binop_on_mux(ir_node *mux, ir_tarval *other,
ir_node *irn_true = new_r_Const(irg, new_true); ir_node *irn_true = new_r_Const(irg, new_true);
ir_node *irn_false = new_r_Const(irg, new_false); ir_node *irn_false = new_r_Const(irg, new_false);
ir_node *block = get_nodes_block(mux); ir_node *block = get_nodes_block(mux);
return new_r_Mux(block, sel, irn_false, irn_true, mode); return new_r_Mux(block, sel, irn_false, irn_true);
} }
/** /**
...@@ -1971,12 +1969,10 @@ static ir_node *apply_binop_on_mux(ir_node *mux, ir_tarval *other, ...@@ -1971,12 +1969,10 @@ static ir_node *apply_binop_on_mux(ir_node *mux, ir_tarval *other,
* @param a the left Mux node * @param a the left Mux node
* @param b the right Mux node * @param b the right Mux node
* @param eval an evaluator function * @param eval an evaluator function
* @param mode the mode of the result, may be different from the mode of the Mux!
* *
* @return a new Mux node if the conversion was successful, NULL else * @return a new Mux node if the conversion was successful, NULL else
*/ */
static ir_node *apply_binop_on_2_muxs(ir_node *a, ir_node *b, tarval_binop eval, static ir_node *apply_binop_on_2_muxs(ir_node *a, ir_node *b, tarval_binop eval)
ir_mode *mode)
{ {
if (!only_one_user(a) || !only_one_user(b)) if (!only_one_user(a) || !only_one_user(b))
return NULL; return NULL;
...@@ -2005,7 +2001,7 @@ static ir_node *apply_binop_on_2_muxs(ir_node *a, ir_node *b, tarval_binop eval, ...@@ -2005,7 +2001,7 @@ static ir_node *apply_binop_on_2_muxs(ir_node *a, ir_node *b, tarval_binop eval,
ir_node *irn_false = new_r_Const(irg, new_false); ir_node *irn_false = new_r_Const(irg, new_false);
ir_node *irn_true = new_r_Const(irg, new_true); ir_node *irn_true = new_r_Const(irg, new_true);
ir_node *block = get_nodes_block(a); ir_node *block = get_nodes_block(a);
return new_r_Mux(block, sel_a, irn_false, irn_true, mode); return new_r_Mux(block, sel_a, irn_false, irn_true);
} else { } else {
return NULL; return NULL;
} }
...@@ -2038,8 +2034,7 @@ static ir_node *apply_unop_on_mux(ir_node *mux, tarval_unop eval) ...@@ -2038,8 +2034,7 @@ static ir_node *apply_unop_on_mux(ir_node *mux, tarval_unop eval)
ir_node *irn_true = new_r_Const(irg, new_true); ir_node *irn_true = new_r_Const(irg, new_true);
ir_node *irn_false = new_r_Const(irg, new_false); ir_node *irn_false = new_r_Const(irg, new_false);
ir_node *block = get_nodes_block(mux); ir_node *block = get_nodes_block(mux);
ir_mode *mode = get_irn_mode(mux); return new_r_Mux(block, sel, irn_false, irn_true);
return new_r_Mux(block, sel, irn_false, irn_true, mode);
} }
/** /**
...@@ -2068,7 +2063,7 @@ static ir_node *apply_conv_on_mux(ir_node *mux, ir_mode *mode) ...@@ -2068,7 +2063,7 @@ static ir_node *apply_conv_on_mux(ir_node *mux, ir_mode *mode)
ir_node *irn_true = new_r_Const(irg, new_true); ir_node *irn_true = new_r_Const(irg, new_true);
ir_node *irn_false = new_r_Const(irg, new_false); ir_node *irn_false = new_r_Const(irg, new_false);
ir_node *block = get_nodes_block(mux); ir_node *block = get_nodes_block(mux);
return new_r_Mux(block, sel, irn_false, irn_true, mode); return new_r_Mux(block, sel, irn_false, irn_true);
} }
/* /*
...@@ -2090,13 +2085,13 @@ static ir_node *apply_conv_on_mux(ir_node *mux, ir_mode *mode) ...@@ -2090,13 +2085,13 @@ static ir_node *apply_conv_on_mux(ir_node *mux, ir_mode *mode)
c = apply_binop_on_2_phis(a, b, eval, mode); \ c = apply_binop_on_2_phis(a, b, eval, mode); \
} else if (is_Const(b) && is_const_Mux(a)) { \ } else if (is_Const(b) && is_const_Mux(a)) { \
/* check for Op(Mux, Const) */ \ /* check for Op(Mux, Const) */ \
c = apply_binop_on_mux(a, get_Const_tarval(b), eval, mode, 0);\ c = apply_binop_on_mux(a, get_Const_tarval(b), eval, 0); \
} else if (is_Const(a) && is_const_Mux(b)) { \ } else if (is_Const(a) && is_const_Mux(b)) { \
/* check for Op(Const, Phi) */ \ /* check for Op(Const, Phi) */ \
c = apply_binop_on_mux(b, get_Const_tarval(a), eval, mode, 1);\ c = apply_binop_on_mux(b, get_Const_tarval(a), eval, 1); \
} else if (is_const_Mux(a) && is_const_Mux(b)) { \ } else if (is_const_Mux(a) && is_const_Mux(b)) { \
/* check for Op(Mux, Mux) */ \ /* check for Op(Mux, Mux) */ \
c = apply_binop_on_2_muxs(a, b, eval, mode); \ c = apply_binop_on_2_muxs(a, b, eval); \
} \ } \
if (c) { \ if (c) { \
DBG_OPT_ALGSIM0(oldn, c); \ DBG_OPT_ALGSIM0(oldn, c); \
...@@ -6965,7 +6960,7 @@ static ir_node *transform_node_Mux(ir_node *n) ...@@ -6965,7 +6960,7 @@ static ir_node *transform_node_Mux(ir_node *n)
/* Mux(x, a, b) => Mux(not(x), b, a) */ /* Mux(x, a, b) => Mux(not(x), b, a) */
sel = new_rd_Cmp(seldbgi, block, cmp_l, cmp_r, relation); sel = new_rd_Cmp(seldbgi, block, cmp_l, cmp_r, relation);
return new_rd_Mux(get_irn_dbg_info(n), get_nodes_block(n), sel, f, t, mode); return new_rd_Mux(get_irn_dbg_info(n), get_nodes_block(n), sel, f, t);
} }
} }
...@@ -6983,13 +6978,13 @@ static ir_node *transform_node_Mux(ir_node *n) ...@@ -6983,13 +6978,13 @@ static ir_node *transform_node_Mux(ir_node *n)
/* Mux(cond0, Mux(cond1, x, y), y) => Mux(cond0 && cond1, x, y) */ /* Mux(cond0, Mux(cond1, x, y), y) => Mux(cond0 && cond1, x, y) */
ir_node* and = new_r_And(block, c0, c1); ir_node* and = new_r_And(block, c0, c1);
DBG_OPT_ALGSIM0(oldn, t1); DBG_OPT_ALGSIM0(oldn, t1);
return new_rd_Mux(dbgi, block, and, f1, t1, mode); return new_rd_Mux(dbgi, block, and, f1, t1);
} else if (f == t1) { } else if (f == t1) {
/* Mux(cond0, Mux(cond1, x, y), x) */ /* Mux(cond0, Mux(cond1, x, y), x) */
ir_node* not_c1 = new_r_Not(block, c1); ir_node* not_c1 = new_r_Not(block, c1);
ir_node* and = new_r_And(block, c0, not_c1); ir_node* and = new_r_And(block, c0, not_c1);
DBG_OPT_ALGSIM0(oldn, f1); DBG_OPT_ALGSIM0(oldn, f1);
return new_rd_Mux(dbgi, block, and, t1, f1, mode); return new_rd_Mux(dbgi, block, and, t1, f1);
} }
} else if (is_Mux(f)) { } else if (is_Mux(f)) {
ir_node *block = get_nodes_block(n); ir_node *block = get_nodes_block(n);
...@@ -7002,13 +6997,13 @@ static ir_node *transform_node_Mux(ir_node *n) ...@@ -7002,13 +6997,13 @@ static ir_node *transform_node_Mux(ir_node *n)
/* Mux(cond0, x, Mux(cond1, x, y)) -> typical if (cond0 || cond1) x else y */ /* Mux(cond0, x, Mux(cond1, x, y)) -> typical if (cond0 || cond1) x else y */
ir_node* or = new_r_Or(block, c0, c1); ir_node* or = new_r_Or(block, c0, c1);
DBG_OPT_ALGSIM0(oldn, f1); DBG_OPT_ALGSIM0(oldn, f1);
return new_rd_Mux(dbgi, block, or, f1, t1, mode); return new_rd_Mux(dbgi, block, or, f1, t1);
} else if (t == f1) { } else if (t == f1) {
/* Mux(cond0, x, Mux(cond1, y, x)) */ /* Mux(cond0, x, Mux(cond1, y, x)) */
ir_node* not_c1 = new_r_Not(block, c1); ir_node* not_c1 = new_r_Not(block, c1);
ir_node* or = new_r_Or(block, c0, not_c1); ir_node* or = new_r_Or(block, c0, not_c1);
DBG_OPT_ALGSIM0(oldn, t1); DBG_OPT_ALGSIM0(oldn, t1);
return new_rd_Mux(dbgi, block, or, t1, f1, mode); return new_rd_Mux(dbgi, block, or, t1, f1);
} }
} }
......
...@@ -1419,7 +1419,7 @@ static ir_node *new_Abs(ir_node *const op, ir_mode *const mode) ...@@ -1419,7 +1419,7 @@ static ir_node *new_Abs(ir_node *const op, ir_mode *const mode)
ir_node *const zero = new_r_Const_null(irg, mode); ir_node *const zero = new_r_Const_null(irg, mode);
ir_node *const cmp = new_r_Cmp(block, op, zero, ir_relation_less); ir_node *const cmp = new_r_Cmp(block, op, zero, ir_relation_less);
ir_node *const minus_op = new_r_Minus(block, op); ir_node *const minus_op = new_r_Minus(block, op);
ir_node *const mux = new_r_Mux(block, cmp, op, minus_op, mode); ir_node *const mux = new_r_Mux(block, cmp, op, minus_op);
return mux; return mux;
} }
......
...@@ -608,6 +608,7 @@ class Mux(Node): ...@@ -608,6 +608,7 @@ class Mux(Node):
("false", "selected if sel input is false"), ("false", "selected if sel input is false"),
("true", "selected if sel input is true"), ("true", "selected if sel input is true"),
] ]
mode = "get_irn_mode(irn_false)"
flags = [] flags = []
@op @op
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment