Commit 60c9f323 authored by Michael Beck's avatar Michael Beck
Browse files

Added new Mux(b, numP, numP) -> numP node

[r4652]
parent e1308e58
......@@ -860,13 +860,30 @@ new_rd_Filter (dbg_info *db, ir_graph *irg, ir_node *block, ir_node *arg, ir_mod
res = optimize_node(res);
IRN_VRFY_IRG(res, irg);
return res;
}
INLINE ir_node *
new_rd_NoMem (ir_graph *irg) {
return irg->no_mem;
}
INLINE ir_node *
new_rd_NoMem (ir_graph *irg)
new_rd_Mux (dbg_info *db, ir_graph *irg, ir_node *block,
ir_node *sel, ir_node *ir_false, ir_node *ir_true, ir_mode *mode)
{
return irg->no_mem;
ir_node *in[3];
ir_node *res;
in[0] = sel;
in[1] = ir_false;
in[2] = ir_true;
res = new_ir_node(db, irg, block, op_Mux, mode, 3, in);
assert(res);
res = optimize_node(res);
IRN_VRFY_IRG(res, irg);
return res;
}
......@@ -1061,6 +1078,10 @@ INLINE ir_node *new_r_Filter (ir_graph *irg, ir_node *block, ir_node *arg,
INLINE ir_node *new_r_NoMem (ir_graph *irg) {
return new_rd_NoMem(irg);
}
INLINE ir_node *new_r_Mux (ir_graph *irg, ir_node *block,
ir_node *sel, ir_node *ir_false, ir_node *ir_true, ir_mode *mode) {
return new_rd_Mux(NULL, irg, block, sel, ir_false, ir_true, mode);
}
/** ********************/
......@@ -2369,6 +2390,13 @@ ir_node *
return __new_d_NoMem();
}
ir_node *
new_d_Mux (dbg_info *db, ir_node *sel, ir_node *ir_false,
ir_node *ir_true, ir_mode *mode) {
return new_rd_Mux (db, current_ir_graph, current_ir_graph->current_block,
sel, ir_false, ir_true, mode);
}
/* ********************************************************************* */
/* Comfortable interface with automatic Phi node construction. */
/* (Uses also constructors of ?? interface, except new_Block. */
......@@ -2678,3 +2706,6 @@ ir_node *new_Filter (ir_node *arg, ir_mode *mode, long proj) {
ir_node *new_NoMem (void) {
return new_d_NoMem();
}
ir_node *new_Mux (ir_node *sel, ir_node *ir_false, ir_node *ir_true, ir_mode *mode) {
return new_d_Mux(NULL, sel, ir_false, ir_true, mode);
}
......@@ -289,6 +289,7 @@
* type *free_type);
* ir_node *new_Proj (ir_node *arg, ir_mode *mode, long proj);
* ir_node *new_NoMem (void);
* ir_node *new_Mux (ir_node *sel, ir_node *ir_false, ir_node *ir_true, ir_mode *mode);
*
* void add_immBlock_pred (ir_node *block, ir_node *jmp);
* void mature_immBlock (ir_node *block);
......@@ -798,6 +799,13 @@
* Output
* The definition valid in this block.
*
* ir_node *new_Mux (ir_node *sel, ir_node *ir_false, ir_node *ir_true, ir_mode *mode)
* -----------------------------------------------------------------------------
*
* Creates a Mux node. This node implements the following semantic:
* If the sel node (which must be of mode_b) evaluates to true, its value is
* ir_true, else ir_false;
*
*
* OPERATIONS TO MANAGE MEMORY EXPLICITLY
* --------------------------------------
......@@ -1734,6 +1742,7 @@ ir_node *new_rd_EndExcept(dbg_info *db, ir_graph *irg, ir_node *block);
*
* The constructor builds the Filter in intraprocedural view.
*
* @param *db A pointer for debug information.
* @param *irg The ir graph the node belong to.
* @param *block The block the node belong to.
* @param *arg The tuple value to project from.
......@@ -1752,6 +1761,21 @@ ir_node *new_rd_Filter (dbg_info *db, ir_graph *irg, ir_node *block, ir_node *ar
*/
ir_node *new_rd_NoMem (ir_graph *irg);
/** Constructor for a Mux node.
*
* Adds the node to the block in current_ir_block.
*
* @param *db A pointer for debug information.
* @param *irg The ir graph the node belong to.
* @param *block The block the node belong to.
* @param *sel The ir_node that calculates the boolean select.
* @param *ir_true The ir_node that calculates the true result.
* @param *ir_false The ir_node that calculates the false result.
* @param *mode The mode of the node (and it_true and ir_false).
*/
ir_node *new_rd_Mux (dbg_info *db, ir_graph *irg, ir_node *block,
ir_node *sel, ir_node *ir_false, ir_node *ir_true, ir_mode *mode);
/*-------------------------------------------------------------------------*/
/* The raw interface without debug support */
/*-------------------------------------------------------------------------*/
......@@ -2384,6 +2408,20 @@ ir_node *new_r_Filter (ir_graph *irg, ir_node *block, ir_node *arg,
*/
ir_node *new_r_NoMem (ir_graph *irg);
/** Constructor for a Mux node.
*
* Adds the node to the block in current_ir_block.
*
* @param *irg The ir graph the node belong to.
* @param *block The block the node belong to.
* @param *sel The ir_node that calculates the boolean select.
* @param *ir_true The ir_node that calculates the true result.
* @param *ir_false The ir_node that calculates the false result.
* @param *mode The mode of the node (and it_true and ir_false).
*/
ir_node *new_r_Mux (ir_graph *irg, ir_node *block,
ir_node *sel, ir_node *ir_false, ir_node *ir_true, ir_mode *mode);
/*-----------------------------------------------------------------------*/
/* The block oriented interface */
/*-----------------------------------------------------------------------*/
......@@ -3066,6 +3104,19 @@ ir_node *new_d_Filter (dbg_info *db, ir_node *arg, ir_mode *mode, long proj);
*/
ir_node *new_d_NoMem (void);
/** Constructor for a Mux node.
*
* Adds the node to the block in current_ir_block.
*
* @param *db A pointer for debug information.
* @param *sel The ir_node that calculates the boolean select.
* @param *ir_true The ir_node that calculates the true result.
* @param *ir_false The ir_node that calculates the false result.
* @param *mode The mode of the node (and it_true and ir_false).
*/
ir_node *new_d_Mux (dbg_info *db, ir_node *sel,
ir_node *ir_false, ir_node *ir_true, ir_mode *mode);
/*-----------------------------------------------------------------------*/
/* The block oriented interface without debug support */
/*-----------------------------------------------------------------------*/
......@@ -3633,6 +3684,17 @@ ir_node *new_Unknown(ir_mode *m);
*/
ir_node *new_NoMem (void);
/** Constructor for a Mux node.
*
* Adds the node to the block in current_ir_block.
*
* @param *sel The ir_node that calculates the boolean select.
* @param *ir_true The ir_node that calculates the true result.
* @param *ir_false The ir_node that calculates the false result.
* @param *mode The mode of the node (and it_true and ir_false).
*/
ir_node *new_Mux (ir_node *sel, ir_node *ir_false, ir_node *ir_true, ir_mode *mode);
/*---------------------------------------------------------------------*/
/* The comfortable interface. */
/* Supports automatic Phi node construction. */
......
......@@ -1844,10 +1844,38 @@ ir_node *get_Filter_cg_pred(ir_node *node, int pos) {
return node->attr.filter.in_cg[pos + 1];
}
/* Mux support */
ir_node *get_Mux_sel (ir_node *node) {
assert(node->op == op_Mux);
return node->in[1];
}
void set_Mux_sel (ir_node *node, ir_node *sel) {
assert(node->op == op_Mux);
node->in[1] = sel;
}
ir_node *get_Mux_false (ir_node *node) {
assert(node->op == op_Mux);
return node->in[2];
}
void set_Mux_false (ir_node *node, ir_node *ir_false) {
assert(node->op == op_Mux);
node->in[2] = ir_false;
}
ir_node *get_Mux_true (ir_node *node) {
assert(node->op == op_Mux);
return node->in[3];
}
void set_Mux_true (ir_node *node, ir_node *ir_true) {
assert(node->op == op_Mux);
node->in[3] = ir_true;
}
ir_graph *
get_irn_irg(const ir_node *node) {
if (get_irn_op(node) != op_Block)
if (! is_Block(node))
node = get_nodes_block(node);
if (is_Bad(node)) /* sometimes bad is predecessor of nodes instead of block: in case of optimization */
node = get_nodes_block(node);
......
......@@ -848,6 +848,14 @@ void set_Confirm_bound (ir_node *node, ir_node *bound);
pn_Cmp get_Confirm_cmp (ir_node *node);
void set_Confirm_cmp (ir_node *node, pn_Cmp cmp);
ir_node *get_Mux_sel (ir_node *node);
void set_Mux_sel (ir_node *node, ir_node *sel);
ir_node *get_Mux_false (ir_node *node);
void set_Mux_false (ir_node *node, ir_node *ir_false);
ir_node *get_Mux_true (ir_node *node);
void set_Mux_true (ir_node *node, ir_node *ir_true);
/*
*
* NAME Auxiliary routines
......
......@@ -88,6 +88,7 @@ ir_op *op_EndReg; ir_op *get_op_EndReg (void) { return op_EndReg; }
ir_op *op_EndExcept; ir_op *get_op_EndExcept (void) { return op_EndExcept; }
ir_op *op_NoMem; ir_op *get_op_NoMem (void) { return op_NoMem; }
ir_op *op_Mux; ir_op *get_op_Mux (void) { return op_Mux; }
/*
......@@ -226,6 +227,7 @@ init_op(void)
op_EndExcept = new_ir_op(iro_EndExcept, "EndExcept", op_pin_state_pinned, X|I, oparity_any, -1, sizeof(end_attr));
op_NoMem = new_ir_op(iro_NoMem, "NoMem", op_pin_state_pinned, 0, oparity_zero, -1, 0);
op_Mux = new_ir_op(iro_Mux, "Mux", op_pin_state_floats, 0, oparity_trinary, -1, 0);
#undef Y
#undef F
......@@ -297,6 +299,7 @@ void finish_op(void) {
free_ir_op (op_EndExcept); op_EndExcept = NULL;
free_ir_op (op_NoMem ); op_NoMem = NULL;
free_ir_op (op_Mux ); op_Mux = NULL;
}
/* Returns the string for the opcode. */
......
......@@ -40,7 +40,7 @@ typedef enum {
iro_Load, iro_Store, iro_Alloc, iro_Free, iro_Sync,
iro_Proj, iro_Tuple, iro_Id, iro_Bad, iro_Confirm,
iro_Unknown, iro_Filter, iro_Break, iro_CallBegin, iro_EndReg, iro_EndExcept,
iro_NoMem,
iro_NoMem, iro_Mux,
iro_MaxOpcode
} opcode;
......@@ -105,6 +105,7 @@ extern ir_op *op_EndReg; ir_op *get_op_EndReg (void);
extern ir_op *op_EndExcept; ir_op *get_op_EndExcept (void);
extern ir_op *op_NoMem; ir_op *get_op_NoMem (void);
extern ir_op *op_Mux; ir_op *get_op_Mux (void);
/** Returns the ident for the opcode name */
ident *get_op_ident(ir_op *op);
......
......@@ -513,6 +513,26 @@ static tarval *computed_value_Proj(ir_node *n)
return tarval_bad;
}
/**
* calculate the value of a Mux: can be evaluated, if the
* sel and the right input are known
*/
static tarval *computed_value_Mux(ir_node *n)
{
ir_node *sel = get_Mux_sel(n);
tarval *ts = value_of(sel);
if (ts == get_tarval_b_true()) {
ir_node *v = get_Mux_true(n);
return value_of(v);
}
else if (ts == get_tarval_b_false()) {
ir_node *v = get_Mux_false(n);
return value_of(v);
}
return tarval_bad;
}
/**
* If the parameter n can be computed, return its value, else tarval_bad.
* Performs constant folding.
......@@ -557,6 +577,7 @@ static ir_op *firm_set_default_computed_value(ir_op *op)
CASE(Rot);
CASE(Conv);
CASE(Proj);
CASE(Mux);
default:
op->computed_value = NULL;
}
......@@ -1062,6 +1083,22 @@ static ir_node *equivalent_node_Id(ir_node *n)
return n;
}
/**
* optimize a Mux
*/
static ir_node *equivalent_node_Mux(ir_node *n)
{
ir_node *sel = get_Mux_sel(n);
tarval *ts = value_of(sel);
if (ts == get_tarval_b_true())
return get_Mux_true(n);
else if (ts == get_tarval_b_false())
return get_Mux_false(n);
return n;
}
/**
* equivalent_node() returns a node equivalent to input n. It skips all nodes that
* perform no actual computation, as, e.g., the Id nodes. It does not create
......@@ -1110,6 +1147,7 @@ static ir_op *firm_set_default_equivalent_node(ir_op *op)
CASE(Phi);
CASE(Proj);
CASE(Id);
CASE(Mux);
default:
op->equivalent_node = NULL;
}
......
......@@ -1129,6 +1129,20 @@ int irn_vrfy_irg(ir_node *n, ir_graph *irg)
);
break;
case iro_Mux:
op1mode = get_irn_mode(in[1]);
op2mode = get_irn_mode(in[2]);
op3mode = get_irn_mode(in[3]);
ASSERT_AND_RET(
/* Mux: BB x b x numP x numP --> numP */
op1mode == mode_b &&
op2mode == mymode &&
op3mode == mymode &&
mode_is_numP(mymode),
"Mux node", 0
);
break;
default:
break;
}
......
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