Added support for Psi nodes
authorMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Thu, 23 Mar 2006 12:19:22 +0000 (12:19 +0000)
committerMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Thu, 23 Mar 2006 12:19:22 +0000 (12:19 +0000)
[r7509]

ir/ir/irnode.c
ir/ir/irnode.h
ir/ir/irnode_t.h

index 5e3ba55..cec30c7 100644 (file)
@@ -1947,30 +1947,101 @@ ir_node *get_Filter_cg_pred(ir_node *node, int pos) {
 
 /* Mux support */
 ir_node *get_Mux_sel   (ir_node *node) {
+  if (node->op == op_Psi) {
+    assert(get_irn_arity(node) == 3);
+    return get_Psi_cond(node, 0);
+  }
   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;
+  if (node->op == op_Psi) {
+    assert(get_irn_arity(node) == 3);
+    set_Psi_cond(node, 0, sel);
+  }
+  else {
+    assert(node->op == op_Mux);
+    node->in[1] = sel;
+  }
 }
 
 ir_node *get_Mux_false (ir_node *node) {
+  if (node->op == op_Psi) {
+    assert(get_irn_arity(node) == 3);
+    return get_Psi_default(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;
+  if (node->op == op_Psi) {
+    assert(get_irn_arity(node) == 3);
+    set_Psi_default(node, ir_false);
+  }
+  else {
+    assert(node->op == op_Mux);
+    node->in[2] = ir_false;
+  }
 }
 
 ir_node *get_Mux_true  (ir_node *node) {
+  if (node->op == op_Psi) {
+    assert(get_irn_arity(node) == 3);
+    return get_Psi_val(node, 0);
+  }
   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;
+  if (node->op == op_Psi) {
+    assert(get_irn_arity(node) == 3);
+    set_Psi_val(node, 0, ir_true);
+  }
+  else {
+    assert(node->op == op_Mux);
+    node->in[3] = ir_true;
+  }
+}
+
+/* Psi support */
+ir_node *get_Psi_cond   (ir_node *node, int pos) {
+  int num_conds = get_irn_arity(node) >> 1;
+  assert(node->op == op_Psi);
+  assert(pos < num_conds);
+  return node->in[1 + 2 * pos];
+}
+
+void     set_Psi_cond   (ir_node *node, int pos, ir_node *cond) {
+  int num_conds = get_irn_arity(node) >> 1;
+  assert(node->op == op_Psi);
+  assert(pos < num_conds);
+  node->in[1 + 2 * pos] = cond;
+}
+
+ir_node *get_Psi_val    (ir_node *node, int pos) {
+  int num_vals = get_irn_arity(node) >> 1;
+  assert(node->op == op_Psi);
+  assert(pos < num_vals);
+  return node->in[1 + 2 * pos + 1];
+}
+
+void     set_Psi_val    (ir_node *node, int pos, ir_node *val) {
+  int num_vals = get_irn_arity(node) >> 1;
+  assert(node->op == op_Psi);
+  assert(pos < num_vals);
+  node->in[1 + 2 * pos + 1] = val;
+}
+
+ir_node *get_Psi_default(ir_node *node) {
+  int def_pos = get_irn_arity(node);
+  assert(node->op == op_Psi);
+  return node->in[def_pos];
+}
+
+void     set_Psi_default(ir_node *node, ir_node *val) {
+  int def_pos = get_irn_arity(node);
+  assert(node->op == op_Psi);
+  node->in[def_pos] = node;
 }
 
 /* CopyB support */
index 59dcb36..ded66c5 100644 (file)
@@ -908,6 +908,10 @@ 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);
 
+/*
+ * Mux Support: Note that Psi nodes with one condition can be handled
+ * like Mux nodes, and the access functions work as expected.
+ */
 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);
@@ -915,6 +919,13 @@ 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);
 
+ir_node *get_Psi_cond   (ir_node *node, int pos);
+void     set_Psi_cond   (ir_node *node, int pos, ir_node *cond);
+ir_node *get_Psi_val    (ir_node *node, int pos);
+void     set_Psi_val    (ir_node *node, int pos, ir_node *val);
+ir_node *get_Psi_default(ir_node *node);
+void     set_Psi_default(ir_node *node, ir_node *val);
+
 /**
  * Projection numbers for result of CopyB node: use for Proj nodes!
  */
@@ -1037,6 +1048,8 @@ int      is_Return (const ir_node *node);
 int      is_Call (const ir_node *node);
 /** returns true if node is a Sel node. */
 int      is_Sel (const ir_node *node);
+/** returns true if node is a Mux node or a Psi with only one condition. */
+int      is_Mux (const ir_node *node);
 /** returns true if node is a Proj node or a Filter node in
  * intraprocedural view */
 int      is_Proj (const ir_node *node);
index 3814fa7..2ce1f91 100644 (file)
@@ -622,6 +622,16 @@ _is_Sel (const ir_node *node) {
   return (node && _get_irn_op(node) == op_Sel);
 }
 
+static INLINE int
+_is_Mux (const ir_node *node) {
+  assert(node);
+  if (node) {
+    ir_op *op = _get_irn_op(node);
+    return (op == op_Mux || ((op == op_Psi) && _get_irn_arity(node) == 3));
+  }
+  return 0;
+}
+
 static INLINE int
 _is_no_Block(const ir_node *node) {
   assert(node && _is_ir_node(node));
@@ -791,6 +801,7 @@ static INLINE void _set_Cond_jmp_pred(ir_node *node, cond_jmp_predicate pred) {
 #define is_Return(node)                       _is_Return(node)
 #define is_Call(node)                         _is_Call(node)
 #define is_Sel(node)                          _is_Sel(node)
+#define is_Mux(node)                          _is_Mux(node)
 #define is_Bad(node)                          _is_Bad(node)
 #define is_no_Block(node)                     _is_no_Block(node)
 #define is_Block(node)                        _is_Block(node)