Added new Mux(b, numP, numP) -> numP node
authorMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Mon, 13 Dec 2004 15:41:44 +0000 (15:41 +0000)
committerMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Mon, 13 Dec 2004 15:41:44 +0000 (15:41 +0000)
[r4652]

ir/ir/ircons.c
ir/ir/ircons.h
ir/ir/irnode.c
ir/ir/irnode.h
ir/ir/irop.c
ir/ir/irop.h
ir/ir/iropt.c
ir/ir/irvrfy.c

index dd9388f..e06428b 100644 (file)
@@ -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);
+}
index 62a8221..ad8346d 100644 (file)
  *               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);
  *    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.                           */
index 108f654..2c44861 100644 (file)
@@ -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);
index 795e330..cbaef7c 100644 (file)
@@ -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
index 2d11465..94b6b70 100644 (file)
@@ -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. */
index 4effc98..6527aa9 100644 (file)
@@ -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);
index 6b3e6b4..3672f04 100644 (file)
@@ -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;
   }
index a7f3ef3..62c86f2 100644 (file)
@@ -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;
     }