From: Matthias Braun Date: Fri, 30 Jul 2010 08:28:45 +0000 (+0000) Subject: bring back Carry and Borrow (firm_decomp apparently uses it) and add a note that... X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;ds=sidebyside;h=d664ad81f7f46a0c91abd34c58a9737c3342c4b0;p=libfirm bring back Carry and Borrow (firm_decomp apparently uses it) and add a note that the backends don't support them [r27849] --- diff --git a/include/libfirm/ircons.h b/include/libfirm/ircons.h index e4a33e99b..cc98fdb5e 100644 --- a/include/libfirm/ircons.h +++ b/include/libfirm/ircons.h @@ -284,6 +284,8 @@ * ir_node *new_Cmp (ir_node *op1, ir_node *op2); * ir_node *new_Conv (ir_node *op, ir_mode *mode); * ir_node *new_Cast (ir_node *op, ir_type *to_tp); + * ir_node *new_Carry (ir_node *op1, ir_node *op2, ir_mode *mode); + * ir_node *new_Borrow (ir_node *op1, ir_node *op2, ir_mode *mode); * ir_node *new_Load (ir_node *store, ir_node *addr, ir_mode *mode, ir_cons_flags flags); * ir_node *new_Store (ir_node *store, ir_node *addr, ir_node *val, ir_cons_flags flags); * ir_node *new_Alloc (ir_node *store, ir_node *count, ir_type *alloc_type, @@ -767,6 +769,18 @@ * * Rotates the operand to the left by k bits. * + * ir_node *new_Carry (ir_node *op1, ir_node *op2, ir_mode *mode) + * ------------------------------------------------------------ + * + * Calculates the Carry value for integer addition. Used only + * in lowering code. + * + * ir_node *new_Borrow (ir_node *op1, ir_node *op2, ir_mode *mode) + * ------------------------------------------------------------ + * + * Calculates the Borrow value for integer substraction. Used only + * in lowering code. + * * ir_node *new_Conv (ir_node *op, ir_mode *mode) * --------------------------------------------- * @@ -1682,6 +1696,32 @@ FIRM_API ir_node *new_rd_strictConv(dbg_info *db, ir_node *block, FIRM_API ir_node *new_rd_Cast(dbg_info *db, ir_node *block, ir_node *op, ir_type *to_tp); +/** Constructor for a Carry node. + * Note: This node is not supported by the backends! Only use for program + * analysis tasks. + * + * @param *db A pointer for debug information. + * @param *block The IR block the node belongs to. + * @param *op1 The first operand. + * @param *op2 The second operand. + * @param *mode The mode of the operands and the result. + */ +FIRM_API ir_node *new_rd_Carry(dbg_info *db, ir_node *block, + ir_node *op1, ir_node *op2, ir_mode *mode); + +/** Constructor for a Borrow node. + * Note: This node is not supported by the backends! Only use for program + * analysis tasks. + * + * @param *db A pointer for debug information. + * @param *block The IR block the node belongs to. + * @param *op1 The first operand. + * @param *op2 The second operand. + * @param *mode The mode of the operands and the result. + */ +FIRM_API ir_node *new_rd_Borrow(dbg_info *db, ir_node *block, + ir_node *op1, ir_node *op2, ir_mode *mode); + /** Constructor for a Phi node. * * @param *db A pointer for debug information. @@ -2394,6 +2434,27 @@ FIRM_API ir_node *new_r_strictConv(ir_node *block, ir_node *op, ir_mode *mode); */ FIRM_API ir_node *new_r_Cast(ir_node *block, ir_node *op, ir_type *to_tp); +/** Constructor for a Carry node. + * + * @param *block The IR block the node belongs to. + * @param *op1 The first operand. + * @param *op2 The second operand. + * @param *mode The mode of the operands and the result. + */ +FIRM_API ir_node *new_r_Carry(ir_node *block, ir_node *op1, ir_node *op2, + ir_mode *mode); + +/** + * Constructor for a Borrow node. + * + * @param *block The IR block the node belongs to. + * @param *op1 The first operand. + * @param *op2 The second operand. + * @param *mode The mode of the operands and the results. + */ +FIRM_API ir_node *new_r_Borrow(ir_node *block, ir_node *op1, ir_node *op2, + ir_mode *mode); + /** Constructor for a Phi node. * * @param *block The IR block the node belongs to. @@ -3162,6 +3223,30 @@ FIRM_API ir_node *new_d_strictConv(dbg_info *db, ir_node *op, ir_mode *mode); */ FIRM_API ir_node *new_d_Cast(dbg_info *db, ir_node *op, ir_type *to_tp); +/** Constructor for a Carry node. + * + * Adds the node to the block in current_ir_block. + * + * @param *db A pointer for debug information. + * @param *op1 The first operand. + * @param *op2 The second operand. + * @param *mode The mode of the operands and the result. + */ +FIRM_API ir_node *new_d_Carry(dbg_info *db, ir_node *op1, ir_node *op2, + ir_mode *mode); + +/** Constructor for a Borrow node. + * + * Adds the node to the block in current_ir_block. + * + * @param *db A pointer for debug information. + * @param *op1 The first operand. + * @param *op2 The second operand. + * @param *mode The mode of the operands and the result. + */ +FIRM_API ir_node *new_d_Borrow(dbg_info *db, ir_node *op1, ir_node *op2, + ir_mode *mode); + /** Constructor for a Phi node. * * Adds the node to the block in current_ir_block. @@ -3871,6 +3956,26 @@ FIRM_API ir_node *new_strictConv(ir_node *op, ir_mode *mode); */ FIRM_API ir_node *new_Cast(ir_node *op, ir_type *to_tp); +/** Constructor for a Carry node. + * + * Adds the node to the block in current_ir_block. + * + * @param *op1 The first operand. + * @param *op2 The second operand. + * @param *mode The mode of the operands and the result. + */ +FIRM_API ir_node *new_Carry(ir_node *op1, ir_node *op2, ir_mode *mode); + +/** Constructor for a Borrow node. + * + * Adds the node to the block in current_ir_block. + * + * @param *op1 The first operand. + * @param *op2 The second operand. + * @param *mode The mode of the operands and the result. + */ +FIRM_API ir_node *new_Borrow(ir_node *op1, ir_node *op2, ir_mode *mode); + /** Constructor for a Phi node. * * Adds the node to the block in current_ir_block. diff --git a/include/libfirm/nodeops.h b/include/libfirm/nodeops.h index 68559b25b..2a74f5dc6 100644 --- a/include/libfirm/nodeops.h +++ b/include/libfirm/nodeops.h @@ -212,12 +212,16 @@ FIRM_API int is_And(const ir_node *node); FIRM_API int is_Bad(const ir_node *node); /** Return true of the node is a Block node. */ FIRM_API int is_Block(const ir_node *node); +/** Return true of the node is a Borrow node. */ +FIRM_API int is_Borrow(const ir_node *node); /** Return true of the node is a Bound node. */ FIRM_API int is_Bound(const ir_node *node); /** Return true of the node is a Builtin node. */ FIRM_API int is_Builtin(const ir_node *node); /** Return true of the node is a Call node. */ FIRM_API int is_Call(const ir_node *node); +/** Return true of the node is a Carry node. */ +FIRM_API int is_Carry(const ir_node *node); /** Return true of the node is a Cast node. */ FIRM_API int is_Cast(const ir_node *node); /** Return true of the node is a Cmp node. */ @@ -342,6 +346,11 @@ void set_And_right(ir_node *node, ir_node *right); +FIRM_API ir_node *get_Borrow_left(const ir_node *node); +void set_Borrow_left(ir_node *node, ir_node *left); +FIRM_API ir_node *get_Borrow_right(const ir_node *node); +void set_Borrow_right(ir_node *node, ir_node *right); + FIRM_API ir_node *get_Bound_mem(const ir_node *node); void set_Bound_mem(ir_node *node, ir_node *mem); FIRM_API ir_node *get_Bound_index(const ir_node *node); @@ -367,6 +376,11 @@ FIRM_API void set_Call_type(ir_node *node, ir_type* type); FIRM_API unsigned get_Call_tail_call(const ir_node *node); FIRM_API void set_Call_tail_call(ir_node *node, unsigned tail_call); +FIRM_API ir_node *get_Carry_left(const ir_node *node); +void set_Carry_left(ir_node *node, ir_node *left); +FIRM_API ir_node *get_Carry_right(const ir_node *node); +void set_Carry_right(ir_node *node, ir_node *right); + FIRM_API ir_node *get_Cast_op(const ir_node *node); void set_Cast_op(ir_node *node, ir_node *op); FIRM_API ir_type* get_Cast_type(const ir_node *node); diff --git a/include/libfirm/opcodes.h b/include/libfirm/opcodes.h index 0926a9b5b..68d1f564b 100644 --- a/include/libfirm/opcodes.h +++ b/include/libfirm/opcodes.h @@ -13,9 +13,11 @@ typedef enum ir_opcode { iro_And, iro_Bad, iro_Block, + iro_Borrow, iro_Bound, iro_Builtin, iro_Call, + iro_Carry, iro_Cast, iro_Cmp, iro_Cond, @@ -94,9 +96,11 @@ FIRM_API ir_op *op_Anchor; FIRM_API ir_op *op_And; FIRM_API ir_op *op_Bad; FIRM_API ir_op *op_Block; +FIRM_API ir_op *op_Borrow; FIRM_API ir_op *op_Bound; FIRM_API ir_op *op_Builtin; FIRM_API ir_op *op_Call; +FIRM_API ir_op *op_Carry; FIRM_API ir_op *op_Cast; FIRM_API ir_op *op_Cmp; FIRM_API ir_op *op_Cond; @@ -151,9 +155,11 @@ FIRM_API ir_op *get_op_Anchor(void); FIRM_API ir_op *get_op_And(void); FIRM_API ir_op *get_op_Bad(void); FIRM_API ir_op *get_op_Block(void); +FIRM_API ir_op *get_op_Borrow(void); FIRM_API ir_op *get_op_Bound(void); FIRM_API ir_op *get_op_Builtin(void); FIRM_API ir_op *get_op_Call(void); +FIRM_API ir_op *get_op_Carry(void); FIRM_API ir_op *get_op_Cast(void); FIRM_API ir_op *get_op_Cmp(void); FIRM_API ir_op *get_op_Cond(void); diff --git a/ir/ana/vrp.c b/ir/ana/vrp.c index fb2f0e979..6a623f089 100644 --- a/ir/ana/vrp.c +++ b/ir/ana/vrp.c @@ -363,9 +363,9 @@ static int vrp_update_node(ir_node *node) /* TODO: Check, if there can be information derived from any of these: - is_Abs(node) is_Alloc(node) is_Anchor(node) is_Bound(node) + is_Abs(node) is_Alloc(node) is_Anchor(node) is_Borrow(node) is_Bound(node) is_Break(node) is_Builtin(node) is_Call(node) - is_Cast(node) is_Cmp(node) is_Cond(node) + is_Carry(node) is_Cast(node) is_Cmp(node) is_Cond(node) is_CopyB(node) is_Div(node) is_DivMod(node) is_Dummy(node) is_End(node) is_Free(node) is_IJmp(node) is_InstOf(node) is_Jmp(node) is_Load(node) is_Minus(node) diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index 8abe0c298..ce18fccc7 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -159,6 +159,50 @@ static tarval *computed_value_Sub(const ir_node *n) return tarval_bad; } /* computed_value_Sub */ +/** + * Return the value of a Carry. + * Special : a op 0, 0 op b + */ +static tarval *computed_value_Carry(const ir_node *n) +{ + ir_node *a = get_binop_left(n); + ir_node *b = get_binop_right(n); + ir_mode *m = get_irn_mode(n); + + tarval *ta = value_of(a); + tarval *tb = value_of(b); + + if ((ta != tarval_bad) && (tb != tarval_bad)) { + tarval_add(ta, tb); + return tarval_carry() ? get_mode_one(m) : get_mode_null(m); + } else { + if (tarval_is_null(ta) || tarval_is_null(tb)) + return get_mode_null(m); + } + return tarval_bad; +} /* computed_value_Carry */ + +/** + * Return the value of a Borrow. + * Special : a op 0 + */ +static tarval *computed_value_Borrow(const ir_node *n) +{ + ir_node *a = get_binop_left(n); + ir_node *b = get_binop_right(n); + ir_mode *m = get_irn_mode(n); + + tarval *ta = value_of(a); + tarval *tb = value_of(b); + + if ((ta != tarval_bad) && (tb != tarval_bad)) { + return tarval_cmp(ta, tb) == pn_Cmp_Lt ? get_mode_one(m) : get_mode_null(m); + } else if (tarval_is_null(ta)) { + return get_mode_null(m); + } + return tarval_bad; +} /* computed_value_Borrow */ + /** * Return the value of an unary Minus. */ @@ -686,6 +730,8 @@ static ir_op_ops *firm_set_default_computed_value(ir_opcode code, ir_op_ops *ops CASE(SymConst); CASE(Add); CASE(Sub); + CASE(Carry); + CASE(Borrow); CASE(Minus); CASE(Mul); CASE(Abs); diff --git a/scripts/ir_spec.py b/scripts/ir_spec.py index d887f5fdc..12702c683 100755 --- a/scripts/ir_spec.py +++ b/scripts/ir_spec.py @@ -170,6 +170,9 @@ class Block(Op): } ''' +class Borrow(Binop): + flags = [] + class Bound(Op): ins = [ "mem", "index", "lower", "upper" ] outs = [ @@ -239,6 +242,9 @@ class Call(Op): assert((get_unknown_type() == type) || is_Method_type(type)); ''' +class Carry(Binop): + flags = [ "commutative" ] + class Cast(Unop): mode = "get_irn_mode(irn_op)" flags = [ "highlevel" ]