From: Michael Beck Date: Thu, 23 Mar 2006 12:19:22 +0000 (+0000) Subject: Added support for Psi nodes X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=ef2b291b6f9191c63684513962ea516cba8f94e5;p=libfirm Added support for Psi nodes [r7509] --- diff --git a/ir/ir/irnode.c b/ir/ir/irnode.c index 5e3ba5588..cec30c774 100644 --- a/ir/ir/irnode.c +++ b/ir/ir/irnode.c @@ -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 */ diff --git a/ir/ir/irnode.h b/ir/ir/irnode.h index 59dcb36dd..ded66c56d 100644 --- a/ir/ir/irnode.h +++ b/ir/ir/irnode.h @@ -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); diff --git a/ir/ir/irnode_t.h b/ir/ir/irnode_t.h index 3814fa7c5..2ce1f91ad 100644 --- a/ir/ir/irnode_t.h +++ b/ir/ir/irnode_t.h @@ -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)