From 31fc92ec27c0274f5f24c515094afd40a04ab1a9 Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Wed, 9 Feb 2011 13:55:18 +0000 Subject: [PATCH] remove Quot node (just use Div instead) [r28346] --- include/libfirm/ircons.h | 14 -- include/libfirm/irnode.h | 4 +- include/libfirm/tv.h | 10 -- ir/ana/vrp.c | 2 +- ir/be/TEMPLATE/TEMPLATE_transform.c | 6 +- ir/be/arm/arm_transform.c | 34 +++-- ir/be/ia32/ia32_transform.c | 143 +++++++++----------- ir/be/sparc/sparc_transform.c | 37 +----- ir/ir/irdump.c | 11 -- ir/ir/irnode.c | 1 - ir/ir/iropt.c | 194 ++++++++-------------------- ir/ir/irtypes.h | 2 +- ir/ir/irverify.c | 63 +-------- ir/lower/lower_intrinsics.c | 13 +- ir/opt/opt_ldst.c | 3 +- ir/stat/firmstat.c | 14 -- ir/stat/firmstat_t.h | 1 - ir/tv/tv.c | 46 +++---- scripts/ir_spec.py | 29 +---- 19 files changed, 175 insertions(+), 452 deletions(-) diff --git a/include/libfirm/ircons.h b/include/libfirm/ircons.h index 7fee219c9..171eebcdb 100644 --- a/include/libfirm/ircons.h +++ b/include/libfirm/ircons.h @@ -268,7 +268,6 @@ * ir_node *new_Minus (ir_node *op, ir_mode *mode); * ir_node *new_Mul (ir_node *op1, ir_node *op2, ir_mode *mode); * ir_node *new_Mulh (ir_node *op1, ir_node *op2, ir_mode *mode); - * ir_node *new_Quot (ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode, op_pin_state state); * ir_node *new_Div (ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode, op_pin_state state); * ir_node *new_Mod (ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode, op_pin_state state; * ir_node *new_And (ir_node *op1, ir_node *op2, ir_mode *mode); @@ -686,19 +685,6 @@ * * Returns the high order bits of a n*n=2n multiplication. * - * ir_node *new_Quot (ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode, op_pin_state state) - * ------------------------------------------------------------------------------------------------- - * - * Quot performs exact division of floating point numbers. It's mode - * is Tuple, the mode of the result must match the Proj mode - * that extracts the result of the arithmetic operations. - * - * Inputs: - * The store needed to model exceptions and the two operands. - * Output: - * A tuple containing a memory and a execution for modeling exceptions - * and the result of the arithmetic operation. - * * ir_node *new_Div (ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode, op_pin_state state) * ------------------------------------------------------------------------------------------------ * diff --git a/include/libfirm/irnode.h b/include/libfirm/irnode.h index c142758a4..764acb20a 100644 --- a/include/libfirm/irnode.h +++ b/include/libfirm/irnode.h @@ -482,7 +482,7 @@ FIRM_API const char *get_builtin_kind_name(ir_builtin_kind kind); operands can be factored out. Left is the first, right the second arithmetic value as listed in tech report 1999-44. unops are: Minus, Abs, Not, Conv, Cast - binops are: Add, Sub, Mul, Quot, Div, Mod, And, Or, Eor, Shl, + binops are: Add, Sub, Mul, Div, Mod, And, Or, Eor, Shl, Shr, Shrs, Rotl, Cmp */ FIRM_API int is_unop(const ir_node *node); FIRM_API ir_node *get_unop_op(const ir_node *node); @@ -619,7 +619,7 @@ FIRM_API ir_node *skip_HighLevel_ops(ir_node *node); FIRM_API int is_cfop(const ir_node *node); /** Returns true if the operation can change the control flow because - of an exception: Call, Quot, Div, Mod, Load, Store, Alloc, + of an exception: Call, Div, Mod, Load, Store, Alloc, Bad. Raise is not fragile, but a unconditional jump. */ FIRM_API int is_fragile_op(const ir_node *node); /** Returns the memory operand of fragile operations. */ diff --git a/include/libfirm/tv.h b/include/libfirm/tv.h index 59fdf247a..37487c871 100644 --- a/include/libfirm/tv.h +++ b/include/libfirm/tv.h @@ -522,16 +522,6 @@ FIRM_API ir_tarval *tarval_sub(ir_tarval *a, ir_tarval *b, ir_mode *dst_mode); */ FIRM_API ir_tarval *tarval_mul(ir_tarval *a, ir_tarval *b); -/** - * Division of two floating point tarvals. - * - * @param a the first tarval - * @param b the second tarval - * - * @return a / b or tarval_bad - */ -FIRM_API ir_tarval *tarval_quo(ir_tarval *a, ir_tarval *b); - /** * Integer division of two tarvals. * diff --git a/ir/ana/vrp.c b/ir/ana/vrp.c index 10d189679..b86ebe6de 100644 --- a/ir/ana/vrp.c +++ b/ir/ana/vrp.c @@ -370,7 +370,7 @@ static int vrp_update_node(ir_node *node) is_End(node) is_Free(node) is_IJmp(node) is_InstOf(node) is_Jmp(node) is_Load(node) is_Minus(node) is_Mod(node) is_Mul(node) is_Mulh(node) is_Mux(node) is_NoMem(node) - is_Pin(node) is_Proj(node) is_Quot(node) + is_Pin(node) is_Proj(node) is_Raise(node) is_Return(node) is_Sel(node) is_Start(node) is_Store(node) is_SymConst(node) is_Sync(node) is_Tuple(node) */ diff --git a/ir/be/TEMPLATE/TEMPLATE_transform.c b/ir/be/TEMPLATE/TEMPLATE_transform.c index 79a1125ea..1a0dc1a6e 100644 --- a/ir/be/TEMPLATE/TEMPLATE_transform.c +++ b/ir/be/TEMPLATE/TEMPLATE_transform.c @@ -77,8 +77,10 @@ static ir_node *gen_Eor(ir_node *node) return transform_binop(node, new_bd_TEMPLATE_Xor); } -static ir_node *gen_Quot(ir_node *node) +static ir_node *gen_Div(ir_node *node) { + ir_mode *mode = get_Div_resmode(node); + assert(mode_is_float(mode)); return transform_binop(node, new_bd_TEMPLATE_fDiv); } @@ -254,6 +256,7 @@ static void TEMPLATE_register_transformers(void) be_set_transform_function(op_Add, gen_Add); be_set_transform_function(op_And, gen_And); be_set_transform_function(op_Const, gen_Const); + be_set_transform_function(op_Div, gen_Div); be_set_transform_function(op_Eor, gen_Eor); be_set_transform_function(op_Jmp, gen_Jmp); be_set_transform_function(op_Load, gen_Load); @@ -262,7 +265,6 @@ static void TEMPLATE_register_transformers(void) be_set_transform_function(op_Not, gen_Not); be_set_transform_function(op_Or, gen_Or); be_set_transform_function(op_Phi, gen_Phi); - be_set_transform_function(op_Quot, gen_Quot); be_set_transform_function(op_Shl, gen_Shl); be_set_transform_function(op_Shr, gen_Shr); be_set_transform_function(op_Store, gen_Store); diff --git a/ir/be/arm/arm_transform.c b/ir/be/arm/arm_transform.c index b582969c2..c357f5bfa 100644 --- a/ir/be/arm/arm_transform.c +++ b/ir/be/arm/arm_transform.c @@ -568,17 +568,19 @@ static ir_node *gen_Mul(ir_node *node) return new_bd_arm_Mul(dbg, block, new_op1, new_op2); } -static ir_node *gen_Quot(ir_node *node) +static ir_node *gen_Div(ir_node *node) { ir_node *block = be_transform_node(get_nodes_block(node)); - ir_node *op1 = get_Quot_left(node); + ir_node *op1 = get_Div_left(node); ir_node *new_op1 = be_transform_node(op1); - ir_node *op2 = get_Quot_right(node); + ir_node *op2 = get_Div_right(node); ir_node *new_op2 = be_transform_node(op2); - ir_mode *mode = get_irn_mode(node); + ir_mode *mode = get_Div_resmode(node); dbg_info *dbg = get_irn_dbg_info(node); assert(mode != mode_E && "IEEE Extended FP not supported"); + /* integer division should be replaced by builtin call */ + assert(mode_is_float(mode)); if (USE_FPA(isa)) { return new_bd_arm_Dvf(dbg, block, new_op1, new_op2, mode); @@ -1378,7 +1380,7 @@ static ir_node *gen_Proj_CopyB(ir_node *node) panic("Unsupported Proj from CopyB"); } -static ir_node *gen_Proj_Quot(ir_node *node) +static ir_node *gen_Proj_Div(ir_node *node) { ir_node *pred = get_Proj_pred(node); ir_node *new_pred = be_transform_node(pred); @@ -1387,20 +1389,14 @@ static ir_node *gen_Proj_Quot(ir_node *node) long proj = get_Proj_proj(node); switch (proj) { - case pn_Quot_M: - if (is_arm_Dvf(new_pred)) { - return new_rd_Proj(dbgi, new_pred, mode_M, pn_arm_Dvf_M); - } - break; - case pn_Quot_res: - if (is_arm_Dvf(new_pred)) { - return new_rd_Proj(dbgi, new_pred, mode, pn_arm_Dvf_res); - } - break; + case pn_Div_M: + return new_rd_Proj(dbgi, new_pred, mode_M, pn_arm_Dvf_M); + case pn_Div_res: + return new_rd_Proj(dbgi, new_pred, mode, pn_arm_Dvf_res); default: break; } - panic("Unsupported Proj from Quot"); + panic("Unsupported Proj from Div"); } /** @@ -1592,8 +1588,8 @@ static ir_node *gen_Proj(ir_node *node) return gen_Proj_Call(node); case iro_CopyB: return gen_Proj_CopyB(node); - case iro_Quot: - return gen_Proj_Quot(node); + case iro_Div: + return gen_Proj_Div(node); case iro_Cmp: return gen_Proj_Cmp(node); case iro_Start: @@ -2095,6 +2091,7 @@ static void arm_register_transformers(void) be_set_transform_function(op_Const, gen_Const); be_set_transform_function(op_Conv, gen_Conv); be_set_transform_function(op_CopyB, gen_CopyB); + be_set_transform_function(op_Div, gen_Div); be_set_transform_function(op_Eor, gen_Eor); be_set_transform_function(op_Jmp, gen_Jmp); be_set_transform_function(op_Load, gen_Load); @@ -2104,7 +2101,6 @@ static void arm_register_transformers(void) be_set_transform_function(op_Or, gen_Or); be_set_transform_function(op_Phi, gen_Phi); be_set_transform_function(op_Proj, gen_Proj); - be_set_transform_function(op_Quot, gen_Quot); be_set_transform_function(op_Return, gen_Return); be_set_transform_function(op_Rotl, gen_Rotl); be_set_transform_function(op_Sel, gen_Sel); diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index a7ff792d5..ef3ea36b7 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -1069,8 +1069,6 @@ static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2, if (mode == mode_T) { if (is_Div(node)) mode = get_Div_resmode(node); - else if (is_Mod(node)) - mode = get_Mod_resmode(node); else panic("can't determine mode"); } @@ -1618,27 +1616,20 @@ static ir_node *gen_Mod(ir_node *node) */ static ir_node *gen_Div(ir_node *node) { - return create_Div(node); -} - - -/** - * Creates an ia32 floating Div. - * - * @return The created ia32 xDiv node - */ -static ir_node *gen_Quot(ir_node *node) -{ - ir_node *op1 = get_Quot_left(node); - ir_node *op2 = get_Quot_right(node); + ir_mode *mode = get_Div_resmode(node); + if (mode_is_float(mode)) { + ir_node *op1 = get_Div_left(node); + ir_node *op2 = get_Div_right(node); - if (ia32_cg_config.use_sse2) { - return gen_binop(node, op1, op2, new_bd_ia32_xDiv, match_am); - } else { - return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfdiv); + if (ia32_cg_config.use_sse2) { + return gen_binop(node, op1, op2, new_bd_ia32_xDiv, match_am); + } else { + return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfdiv); + } } -} + return create_Div(node); +} /** * Creates an ia32 Shl. @@ -4576,7 +4567,7 @@ static ir_node *gen_Proj_Load(ir_node *node) /** * Transform and renumber the Projs from a Div or Mod instruction. */ -static ir_node *gen_Proj_Div_Mod(ir_node *node) +static ir_node *gen_Proj_Div(ir_node *node) { ir_node *block = be_transform_node(get_nodes_block(node)); ir_node *pred = get_Proj_pred(node); @@ -4584,73 +4575,74 @@ static ir_node *gen_Proj_Div_Mod(ir_node *node) dbg_info *dbgi = get_irn_dbg_info(node); long proj = get_Proj_proj(node); - assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)); + assert(pn_ia32_Div_M == pn_ia32_IDiv_M); + assert(pn_ia32_Div_div_res == pn_ia32_IDiv_div_res); - switch (get_irn_opcode(pred)) { - case iro_Div: - switch (proj) { - case pn_Div_M: + switch (proj) { + case pn_Div_M: + if (is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)) { return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Div_M); - case pn_Div_res: - return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_div_res); - case pn_Div_X_regular: - return new_rd_Jmp(dbgi, block); - case pn_Div_X_except: - set_ia32_exc_label(new_pred, 1); - return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_exc); - default: - break; + } else if (is_ia32_xDiv(new_pred)) { + return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_xDiv_M); + } else if (is_ia32_vfdiv(new_pred)) { + return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_vfdiv_M); + } else { + panic("Div transformed to unexpected thing %+F", new_pred); } - break; - case iro_Mod: - switch (proj) { - case pn_Mod_M: - return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Div_M); - case pn_Mod_res: - return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_mod_res); - case pn_Mod_X_except: - set_ia32_exc_label(new_pred, 1); - return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_exc); - default: - break; + case pn_Div_res: + if (is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)) { + return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_div_res); + } else if (is_ia32_xDiv(new_pred)) { + return new_rd_Proj(dbgi, new_pred, mode_xmm, pn_ia32_xDiv_res); + } else if (is_ia32_vfdiv(new_pred)) { + return new_rd_Proj(dbgi, new_pred, mode_vfp, pn_ia32_vfdiv_res); + } else { + panic("Div transformed to unexpected thing %+F", new_pred); } - break; + case pn_Div_X_regular: + return new_rd_Jmp(dbgi, block); + case pn_Div_X_except: + set_ia32_exc_label(new_pred, 1); + return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_exc); default: break; } - panic("No idea how to transform proj->Div/Mod"); + panic("No idea how to transform proj->Div"); } /** - * Transform and renumber the Projs from a CopyB. + * Transform and renumber the Projs from a Div or Mod instruction. */ -static ir_node *gen_Proj_CopyB(ir_node *node) +static ir_node *gen_Proj_Mod(ir_node *node) { ir_node *pred = get_Proj_pred(node); ir_node *new_pred = be_transform_node(pred); dbg_info *dbgi = get_irn_dbg_info(node); long proj = get_Proj_proj(node); + assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)); + assert(pn_ia32_Div_M == pn_ia32_IDiv_M); + assert(pn_ia32_Div_mod_res == pn_ia32_IDiv_mod_res); + switch (proj) { - case pn_CopyB_M: - if (is_ia32_CopyB_i(new_pred)) { - return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_i_M); - } else if (is_ia32_CopyB(new_pred)) { - return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_M); - } - break; + case pn_Mod_M: + return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Div_M); + case pn_Mod_res: + return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_mod_res); + case pn_Mod_X_except: + set_ia32_exc_label(new_pred, 1); + return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_exc); default: break; } - - panic("No idea how to transform proj->CopyB"); + panic("No idea how to transform proj->Mod"); } /** - * Transform and renumber the Projs from a Quot. + * Transform and renumber the Projs from a CopyB. */ -static ir_node *gen_Proj_Quot(ir_node *node) +static ir_node *gen_Proj_CopyB(ir_node *node) { ir_node *pred = get_Proj_pred(node); ir_node *new_pred = be_transform_node(pred); @@ -4658,27 +4650,18 @@ static ir_node *gen_Proj_Quot(ir_node *node) long proj = get_Proj_proj(node); switch (proj) { - case pn_Quot_M: - if (is_ia32_xDiv(new_pred)) { - return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_xDiv_M); - } else if (is_ia32_vfdiv(new_pred)) { - return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_vfdiv_M); - } - break; - case pn_Quot_res: - if (is_ia32_xDiv(new_pred)) { - return new_rd_Proj(dbgi, new_pred, mode_xmm, pn_ia32_xDiv_res); - } else if (is_ia32_vfdiv(new_pred)) { - return new_rd_Proj(dbgi, new_pred, mode_vfp, pn_ia32_vfdiv_res); + case pn_CopyB_M: + if (is_ia32_CopyB_i(new_pred)) { + return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_i_M); + } else if (is_ia32_CopyB(new_pred)) { + return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_M); } break; - case pn_Quot_X_regular: - case pn_Quot_X_except: default: break; } - panic("No idea how to transform proj->Quot"); + panic("No idea how to transform proj->CopyB"); } static ir_node *gen_be_Call(ir_node *node) @@ -5598,12 +5581,11 @@ static ir_node *gen_Proj(ir_node *node) case iro_Builtin: return gen_Proj_Builtin(node); case iro_Div: + return gen_Proj_Div(node); case iro_Mod: - return gen_Proj_Div_Mod(node); + return gen_Proj_Mod(node); case iro_CopyB: return gen_Proj_CopyB(node); - case iro_Quot: - return gen_Proj_Quot(node); case beo_SubSP: return gen_Proj_be_SubSP(node); case beo_AddSP: @@ -5713,7 +5695,6 @@ static void register_transformers(void) be_set_transform_function(op_Or, gen_Or); be_set_transform_function(op_Phi, gen_Phi); be_set_transform_function(op_Proj, gen_Proj); - be_set_transform_function(op_Quot, gen_Quot); be_set_transform_function(op_Rotl, gen_Rotl); be_set_transform_function(op_Shl, gen_Shl); be_set_transform_function(op_Shr, gen_Shr); diff --git a/ir/be/sparc/sparc_transform.c b/ir/be/sparc/sparc_transform.c index 8170137da..5395ea2c5 100644 --- a/ir/be/sparc/sparc_transform.c +++ b/ir/be/sparc/sparc_transform.c @@ -640,7 +640,11 @@ static ir_node *gen_Div(ir_node *node) ir_node *right = get_Div_right(node); ir_node *res; - assert(!mode_is_float(mode)); + if (mode_is_float(mode)) { + return gen_helper_binfpop(node, mode, new_bd_sparc_fdiv_s, + new_bd_sparc_fdiv_d, new_bd_sparc_fdiv_q); + } + if (mode_is_signed(mode)) { ir_node *left_high = gen_sign_extension_value(left); @@ -669,14 +673,6 @@ static ir_node *gen_Div(ir_node *node) return res; } -static ir_node *gen_Quot(ir_node *node) -{ - ir_mode *mode = get_Quot_resmode(node); - assert(mode_is_float(mode)); - return gen_helper_binfpop(node, mode, new_bd_sparc_fdiv_s, - new_bd_sparc_fdiv_d, new_bd_sparc_fdiv_q); -} - #if 0 static ir_node *gen_Abs(ir_node *node) { @@ -1844,6 +1840,8 @@ static ir_node *gen_Proj_Div(ir_node *node) assert(is_sparc_SDiv(new_pred) || is_sparc_UDiv(new_pred)); assert((int)pn_sparc_SDiv_res == (int)pn_sparc_UDiv_res); assert((int)pn_sparc_SDiv_M == (int)pn_sparc_UDiv_M); + assert((int)pn_sparc_SDiv_res == (int)pn_sparc_fdiv_res); + assert((int)pn_sparc_SDiv_M == (int)pn_sparc_fdiv_M); switch (pn) { case pn_Div_res: return new_r_Proj(new_pred, mode_gp, pn_sparc_SDiv_res); @@ -1855,24 +1853,6 @@ static ir_node *gen_Proj_Div(ir_node *node) panic("Unsupported Proj from Div"); } -static ir_node *gen_Proj_Quot(ir_node *node) -{ - ir_node *pred = get_Proj_pred(node); - ir_node *new_pred = be_transform_node(pred); - long pn = get_Proj_proj(node); - - assert(is_sparc_fdiv(new_pred)); - switch (pn) { - case pn_Quot_res: - return new_r_Proj(new_pred, mode_gp, pn_sparc_fdiv_res); - case pn_Quot_M: - return new_r_Proj(new_pred, mode_gp, pn_sparc_fdiv_M); - default: - break; - } - panic("Unsupported Proj from Quot"); -} - static ir_node *get_frame_base(void) { const arch_register_t *reg = cconv->omit_fp ? sp_reg : fp_reg; @@ -2047,8 +2027,6 @@ static ir_node *gen_Proj(ir_node *node) return be_duplicate_node(node); case iro_Div: return gen_Proj_Div(node); - case iro_Quot: - return gen_Proj_Quot(node); case iro_Start: return gen_Proj_Start(node); case iro_Proj: { @@ -2102,7 +2080,6 @@ static void sparc_register_transformers(void) be_set_transform_function(op_Or, gen_Or); be_set_transform_function(op_Phi, gen_Phi); be_set_transform_function(op_Proj, gen_Proj); - be_set_transform_function(op_Quot, gen_Quot); be_set_transform_function(op_Return, gen_Return); be_set_transform_function(op_Sel, gen_Sel); be_set_transform_function(op_Shl, gen_Shl); diff --git a/ir/ir/irdump.c b/ir/ir/irdump.c index 84b329ddc..ef5c91019 100644 --- a/ir/ir/irdump.c +++ b/ir/ir/irdump.c @@ -832,16 +832,6 @@ static const pns_lookup_t call_lut[] = { #undef X }; -/** the lookup table for Proj(Quot) names */ -static const pns_lookup_t quot_lut[] = { -#define X(a) { pn_Quot_##a, #a } - X(M), - X(X_regular), - X(X_except), - X(res) -#undef X -}; - /** the lookup table for Proj(Div) names */ static const pns_lookup_t div_lut[] = { #define X(a) { pn_Div_##a, #a } @@ -934,7 +924,6 @@ static const proj_lookup_t proj_lut[] = { { iro_Start, E(start_lut) }, { iro_Cond, E(cond_lut) }, { iro_Call, E(call_lut) }, - { iro_Quot, E(quot_lut) }, { iro_Div, E(div_lut) }, { iro_Mod, E(mod_lut) }, { iro_Load, E(load_lut) }, diff --git a/ir/ir/irnode.c b/ir/ir/irnode.c index 171b484ef..707b05081 100644 --- a/ir/ir/irnode.c +++ b/ir/ir/irnode.c @@ -1575,7 +1575,6 @@ ir_node *get_fragile_op_mem(ir_node *node) switch (get_irn_opcode(node)) { case iro_Call : - case iro_Quot : case iro_Div : case iro_Mod : case iro_Load : diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index ddea97b14..2eb25b1ce 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -543,20 +543,6 @@ static ir_tarval *computed_value_Proj_Cmp(const ir_node *n) return computed_value_Cmp_Confirm(cmp, left, right, pn_cmp); } /* computed_value_Proj_Cmp */ -/** - * Return the value of a floating point Quot. - */ -static ir_tarval *do_computed_value_Quot(const ir_node *a, const ir_node *b) -{ - ir_tarval *ta = value_of(a); - ir_tarval *tb = value_of(b); - - /* cannot optimize 0 / b = 0 because of NaN */ - if (ta != tarval_bad && tb != tarval_bad) - return tarval_quo(ta, tb); - return tarval_bad; -} /* do_computed_value_Quot */ - /** * Calculate the value of an integer Div of two nodes. * Special case: 0 / b @@ -621,20 +607,6 @@ static ir_tarval *computed_value_Proj_Mod(const ir_node *n) return tarval_bad; } /* computed_value_Proj_Mod */ -/** - * Return the value of a Proj(Quot). - */ -static ir_tarval *computed_value_Proj_Quot(const ir_node *n) -{ - long proj_nr = get_Proj_proj(n); - - if (proj_nr == pn_Quot_res) { - const ir_node *a = get_Proj_pred(n); - return do_computed_value_Quot(get_Quot_left(a), get_Quot_right(a)); - } - return tarval_bad; -} /* computed_value_Proj_Quot */ - /** * Return the value of a Proj. */ @@ -707,7 +679,6 @@ static ir_op_ops *firm_set_default_computed_value(ir_opcode code, ir_op_ops *ops CASE_PROJ(Cmp); CASE_PROJ(Div); CASE_PROJ(Mod); - CASE_PROJ(Quot); CASE(Proj); default: /* leave NULL */ @@ -1514,38 +1485,6 @@ static ir_node *equivalent_node_Proj_Div(ir_node *proj) return proj; } /* equivalent_node_Proj_Div */ -/** - * Optimize a / 1.0 = a. - */ -static ir_node *equivalent_node_Proj_Quot(ir_node *proj) -{ - ir_node *oldn = proj; - ir_node *quot = get_Proj_pred(proj); - ir_node *b = get_Quot_right(quot); - ir_tarval *tb = value_of(b); - - /* Div is not commutative. */ - if (tarval_is_one(tb)) { /* Quot(x, 1) == x */ - switch (get_Proj_proj(proj)) { - case pn_Quot_M: - proj = get_Quot_mem(quot); - DBG_OPT_ALGSIM0(oldn, proj, FS_OPT_NEUTRAL_1); - return proj; - - case pn_Quot_res: - proj = get_Quot_left(quot); - DBG_OPT_ALGSIM0(oldn, proj, FS_OPT_NEUTRAL_1); - return proj; - - default: - /* we cannot replace the exception Proj's here, this is done in - transform_node_Proj_Quot() */ - return proj; - } - } - return proj; -} /* equivalent_node_Proj_Quot */ - /** * Optimize CopyB(mem, x, x) into a Nop. */ @@ -1895,7 +1834,6 @@ static ir_op_ops *firm_set_default_equivalent_node(ir_opcode code, ir_op_ops *op CASE(Sync); CASE_PROJ(Tuple); CASE_PROJ(Div); - CASE_PROJ(Quot); CASE_PROJ(CopyB); CASE_PROJ(Bound); CASE_PROJ(Load); @@ -2863,16 +2801,14 @@ static ir_node *transform_node_Div(ir_node *n) DBG_OPT_ALGSIM0(n, value, FS_OPT_CONST_PHI); goto make_tuple; } - } - else if (is_Const(a) && is_const_Phi(b)) { + } else if (is_Const(a) && is_const_Phi(b)) { /* check for Div(Const, Phi) */ value = apply_binop_on_phi(b, get_Const_tarval(a), (eval_func) tarval_div, mode, 1); if (value) { DBG_OPT_ALGSIM0(n, value, FS_OPT_CONST_PHI); goto make_tuple; } - } - else if (is_const_Phi(a) && is_const_Phi(b)) { + } else if (is_const_Phi(a) && is_const_Phi(b)) { /* check for Div(Phi, Phi) */ value = apply_binop_on_2_phis(a, b, (eval_func) tarval_div, mode); if (value) { @@ -2883,27 +2819,65 @@ static ir_node *transform_node_Div(ir_node *n) value = n; - if (a == b && value_not_zero(a, &dummy)) { - ir_graph *irg = get_irn_irg(n); - /* BEWARE: we can optimize a/a to 1 only if this cannot cause a exception */ - value = new_r_Const(irg, get_mode_one(mode)); - DBG_OPT_CSTEVAL(n, value); - goto make_tuple; + if (mode_is_float(mode)) { + /* Optimize x/c to x*(1/c) */ + if (get_mode_arithmetic(mode) == irma_ieee754) { + ir_tarval *tv = value_of(b); + + if (tv != tarval_bad) { + int rem = tarval_fp_ops_enabled(); + + /* + * Floating point constant folding might be disabled here to + * prevent rounding. + * However, as we check for exact result, doing it is safe. + * Switch it on. + */ + tarval_enable_fp_ops(1); + tv = tarval_div(get_mode_one(mode), tv); + tarval_enable_fp_ops(rem); + + /* Do the transformation if the result is either exact or we are + not using strict rules. */ + if (tv != tarval_bad && + (tarval_ieee754_get_exact() || (get_irg_fp_model(get_irn_irg(n)) & fp_strict_algebraic) == 0)) { + ir_node *block = get_nodes_block(n); + ir_graph *irg = get_irn_irg(block); + ir_node *c = new_r_Const(irg, tv); + dbg_info *dbgi = get_irn_dbg_info(n); + value = new_rd_Mul(dbgi, block, a, c, mode); + + goto make_tuple; + } + } + } + } else { - if (mode_is_signed(mode) && is_Const(b)) { - ir_tarval *tv = get_Const_tarval(b); + assert(mode_is_int(mode)); + + if (a == b && value_not_zero(a, &dummy)) { + ir_graph *irg = get_irn_irg(n); + /* BEWARE: we can optimize a/a to 1 only if this cannot cause a exception */ + value = new_r_Const(irg, get_mode_one(mode)); + DBG_OPT_CSTEVAL(n, value); + goto make_tuple; + } else { + if (mode_is_signed(mode) && is_Const(b)) { + ir_tarval *tv = get_Const_tarval(b); - if (tv == get_mode_minus_one(mode)) { - /* a / -1 */ - value = new_rd_Minus(get_irn_dbg_info(n), get_nodes_block(n), a, mode); - DBG_OPT_CSTEVAL(n, value); - goto make_tuple; + if (tv == get_mode_minus_one(mode)) { + /* a / -1 */ + value = new_rd_Minus(get_irn_dbg_info(n), get_nodes_block(n), a, mode); + DBG_OPT_CSTEVAL(n, value); + goto make_tuple; + } } + /* Try architecture dependent optimization */ + value = arch_dep_replace_div_by_const(n); } - /* Try architecture dependent optimization */ - value = arch_dep_replace_div_by_const(n); } + if (value != n) { ir_node *mem, *blk; ir_graph *irg; @@ -3017,56 +2991,6 @@ make_tuple: return n; } /* transform_node_Mod */ -/** - * Optimize x / c to x * (1/c) - */ -static ir_node *transform_node_Quot(ir_node *n) -{ - ir_mode *mode = get_Quot_resmode(n); - ir_node *oldn = n; - - if (get_mode_arithmetic(mode) == irma_ieee754) { - ir_node *b = get_Quot_right(n); - ir_tarval *tv = value_of(b); - - if (tv != tarval_bad) { - int rem = tarval_fp_ops_enabled(); - - /* - * Floating point constant folding might be disabled here to - * prevent rounding. - * However, as we check for exact result, doing it is safe. - * Switch it on. - */ - tarval_enable_fp_ops(1); - tv = tarval_quo(get_mode_one(mode), tv); - tarval_enable_fp_ops(rem); - - /* Do the transformation if the result is either exact or we are not - using strict rules. */ - if (tv != tarval_bad && - (tarval_ieee754_get_exact() || (get_irg_fp_model(get_irn_irg(n)) & fp_strict_algebraic) == 0)) { - ir_node *blk = get_nodes_block(n); - ir_graph *irg = get_irn_irg(blk); - ir_node *c = new_r_Const(irg, tv); - ir_node *a = get_Quot_left(n); - ir_node *m = new_rd_Mul(get_irn_dbg_info(n), blk, a, c, mode); - ir_node *mem = get_Quot_mem(n); - - /* skip a potential Pin */ - mem = skip_Pin(mem); - turn_into_tuple(n, pn_Quot_max); - set_Tuple_pred(n, pn_Quot_M, mem); - set_Tuple_pred(n, pn_Quot_X_regular, new_r_Jmp(blk)); - set_Tuple_pred(n, pn_Quot_X_except, get_irg_bad(irg)); - set_Tuple_pred(n, pn_Quot_res, m); - DBG_OPT_ALGSIM1(oldn, a, b, m, FS_OPT_FP_INV_MUL); - } - } - } - return n; -} /* transform_node_Quot */ - /** * Optimize -a CMP -b into b CMP a. * This works only for for modes where unary Minus @@ -5857,7 +5781,6 @@ static ir_op_ops *firm_set_default_transform_node(ir_opcode code, ir_op_ops *ops CASE(Mul); CASE_PROJ_EX(Div); CASE_PROJ_EX(Mod); - CASE(Quot); CASE_PROJ_EX(Cmp); CASE_PROJ_EX(Cond); CASE(And); @@ -6038,12 +5961,6 @@ static int node_cmp_attr_Mod(ir_node *a, ir_node *b) return node_cmp_attr_Div_Mod(a, b); } /* node_cmp_attr_Mod */ -/** Compares the attributes of two Quot nodes. */ -static int node_cmp_attr_Quot(ir_node *a, ir_node *b) -{ - return node_cmp_attr_Div_Mod(a, b); -} /* node_cmp_attr_Quot */ - /** Compares the attributes of two Confirm nodes. */ static int node_cmp_attr_Confirm(ir_node *a, ir_node *b) { @@ -6146,7 +6063,6 @@ static ir_op_ops *firm_set_default_node_cmp_attr(ir_opcode code, ir_op_ops *ops) CASE(ASM); CASE(Div); CASE(Mod); - CASE(Quot); CASE(Bound); CASE(Builtin); CASE(Dummy); diff --git a/ir/ir/irtypes.h b/ir/ir/irtypes.h index 2c5340b15..a4f4151b8 100644 --- a/ir/ir/irtypes.h +++ b/ir/ir/irtypes.h @@ -289,7 +289,7 @@ typedef struct conv_attr { char strict; /**< If set, this is a strict Conv that cannot be removed. */ } conv_attr; -/** Div/Mod/Quot attribute. */ +/** Div/Mod attribute. */ typedef struct divmod_attr { except_attr exc; /**< The exception attribute. MUST be the first one. */ ir_mode *resmode; /**< Result mode for the division. */ diff --git a/ir/ir/irverify.c b/ir/ir/irverify.c index 4df980042..7280dcf7b 100644 --- a/ir/ir/irverify.c +++ b/ir/ir/irverify.c @@ -432,39 +432,6 @@ static int verify_node_Proj_Call(ir_node *n, ir_node *p) return 1; } -/** - * verify a Proj(Quot) node - */ -static int verify_node_Proj_Quot(ir_node *n, ir_node *p) -{ - ir_mode *mode = get_irn_mode(p); - long proj = get_Proj_proj(p); - - ASSERT_AND_RET_DBG( - ( - (proj == pn_Quot_M && mode == mode_M) || - (proj == pn_Quot_X_regular && mode == mode_X) || - (proj == pn_Quot_X_except && mode == mode_X) || - (proj == pn_Quot_res && mode_is_float(mode) && mode == get_Quot_resmode(n)) - ), - "wrong Proj from Quot", 0, - show_proj_failure(p); - ); - if (proj == pn_Quot_X_regular) - ASSERT_AND_RET( - get_irn_pinned(n) == op_pin_state_pinned, - "Regular Proj from unpinned Quot", 0); - else if (proj == pn_Quot_X_except) - ASSERT_AND_RET( - get_irn_pinned(n) == op_pin_state_pinned, - "Exception Proj from unpinned Quot", 0); - else if (proj == pn_Quot_M) - ASSERT_AND_RET( - get_irn_pinned(n) == op_pin_state_pinned, - "Memory Proj from unpinned Quot", 0); - return 1; -} - /** * verify a Proj(Div) node */ @@ -478,7 +445,7 @@ static int verify_node_Proj_Div(ir_node *n, ir_node *p) (proj == pn_Div_M && mode == mode_M) || (proj == pn_Div_X_regular && mode == mode_X) || (proj == pn_Div_X_except && mode == mode_X) || - (proj == pn_Div_res && mode_is_int(mode) && mode == get_Div_resmode(n)) + (proj == pn_Div_res && mode == get_Div_resmode(n)) ), "wrong Proj from Div", 0, show_proj_failure(p); @@ -511,7 +478,7 @@ static int verify_node_Proj_Mod(ir_node *n, ir_node *p) (proj == pn_Mod_M && mode == mode_M) || (proj == pn_Mod_X_regular && mode == mode_X) || (proj == pn_Mod_X_except && mode == mode_X) || - (proj == pn_Mod_res && mode_is_int(mode) && mode == get_Mod_resmode(n)) + (proj == pn_Mod_res && mode == get_Mod_resmode(n)) ), "wrong Proj from Mod", 0, show_proj_failure(p); @@ -1275,28 +1242,6 @@ static int verify_node_Mulh(ir_node *n, ir_graph *irg) return 1; } -/** - * verify a Quot node - */ -static int verify_node_Quot(ir_node *n, ir_graph *irg) -{ - ir_mode *mymode = get_irn_mode(n); - ir_mode *op1mode = get_irn_mode(get_Quot_mem(n)); - ir_mode *op2mode = get_irn_mode(get_Quot_left(n)); - ir_mode *op3mode = get_irn_mode(get_Quot_right(n)); - (void) irg; - - ASSERT_AND_RET_DBG( - /* Quot: BB x M x float x float --> M x X x float */ - op1mode == mode_M && op2mode == op3mode && - get_mode_sort(op2mode) == irms_float_number && - mymode == mode_T, - "Quot node",0, - show_binop_failure(n, "/* Quot: BB x M x float x float --> M x X x float */"); - ); - return 1; -} - /** * verify a Div node */ @@ -1312,7 +1257,7 @@ static int verify_node_Div(ir_node *n, ir_graph *irg) /* Div: BB x M x int x int --> M x X x int */ op1mode == mode_M && op2mode == op3mode && - mode_is_int(op2mode) && + mode_is_data(op2mode) && mymode == mode_T, "Div node", 0 ); @@ -2156,7 +2101,6 @@ void firm_set_default_verifyer(ir_opcode code, ir_op_ops *ops) CASE(Minus); CASE(Mul); CASE(Mulh); - CASE(Quot); CASE(Div); CASE(Mod); CASE(And); @@ -2196,7 +2140,6 @@ void firm_set_default_verifyer(ir_opcode code, ir_op_ops *ops) CASE(Raise); CASE(InstOf); CASE(Call); - CASE(Quot); CASE(Div); CASE(Mod); CASE(Cmp); diff --git a/ir/lower/lower_intrinsics.c b/ir/lower/lower_intrinsics.c index f78daa8bd..6d48ff6f4 100644 --- a/ir/lower/lower_intrinsics.c +++ b/ir/lower/lower_intrinsics.c @@ -399,14 +399,14 @@ int i_mapper_pow(ir_node *call, void *ctx) if (irn == NULL) { ir_mode *mode = get_irn_mode(left); - ir_node *quot; + ir_node *div; irn = new_r_Const(irg, get_mode_one(mode)); - quot = new_rd_Quot(dbg, block, mem, irn, left, mode, op_pin_state_pinned); - mem = new_r_Proj(quot, mode_M, pn_Quot_M); - irn = new_r_Proj(quot, mode, pn_Quot_res); - reg_jmp = new_r_Proj(quot, mode_X, pn_Quot_X_regular); - exc_jmp = new_r_Proj(quot, mode_X, pn_Quot_X_except); + div = new_rd_Div(dbg, block, mem, irn, left, mode, op_pin_state_pinned); + mem = new_r_Proj(div, mode_M, pn_Div_M); + irn = new_r_Proj(div, mode, pn_Div_res); + reg_jmp = new_r_Proj(div, mode_X, pn_Div_X_regular); + exc_jmp = new_r_Proj(div, mode_X, pn_Div_X_except); } DBG_OPT_ALGSIM0(call, irn, FS_OPT_RTS_POW); replace_call(irn, call, mem, reg_jmp, exc_jmp); @@ -1113,7 +1113,6 @@ static ir_mode *get_irn_res_mode(ir_node *node) { switch (get_irn_opcode(node)) { case iro_Load: return get_Load_mode(node); - case iro_Quot: return get_Quot_resmode(node); case iro_Div: return get_Div_resmode(node); case iro_Mod: return get_Mod_resmode(node); default: return NULL; diff --git a/ir/opt/opt_ldst.c b/ir/opt/opt_ldst.c index 311d68336..ac550616d 100644 --- a/ir/opt/opt_ldst.c +++ b/ir/opt/opt_ldst.c @@ -1201,7 +1201,7 @@ static void update_Call_memop(memop_t *m) } /* update_Call_memop */ /** - * Update a memop for a Div/Mod/Quot. + * Update a memop for a Div/Mod. * * @param m the memop */ @@ -1291,7 +1291,6 @@ static void collect_memops(ir_node *irn, void *ctx) /* we can those to find the memory edge */ break; case iro_Div: - case iro_Quot: case iro_Mod: update_DivOp_memop(op); break; diff --git a/ir/stat/firmstat.c b/ir/stat/firmstat.c index 8dabf6551..5335d02e1 100644 --- a/ir/stat/firmstat.c +++ b/ir/stat/firmstat.c @@ -65,9 +65,6 @@ static ir_op _op_DivC; /** The Div by Const node. */ static ir_op _op_ModC; -/** The Quot by Const node. */ -static ir_op _op_QuotC; - /** The memory Proj node. */ static ir_op _op_ProjM; @@ -590,12 +587,6 @@ static ir_op *stat_get_irn_op(ir_node *node) op = status->op_ModC ? status->op_ModC : op; } /* if */ break; - case iro_Quot: - if (is_Const(get_Quot_right(node))) { - /* special case, a floating point division by a const, count on extra counter */ - op = status->op_QuotC ? status->op_QuotC : op; - } /* if */ - break; case iro_Sel: if (is_Sel(get_Sel_ptr(node))) { /* special case, a Sel of a Sel, count on extra counter */ @@ -2375,16 +2366,12 @@ void firm_init_stat(unsigned enable_options) _op_ModC.code = --num; _op_ModC.name = new_id_from_chars(X("ModC")); - _op_QuotC.code = --num; - _op_QuotC.name = new_id_from_chars(X("QuotC")); - status->op_Phi0 = &_op_Phi0; status->op_PhiM = &_op_PhiM; status->op_ProjM = &_op_ProjM; status->op_MulC = &_op_MulC; status->op_DivC = &_op_DivC; status->op_ModC = &_op_ModC; - status->op_QuotC = &_op_QuotC; } else { status->op_Phi0 = NULL; status->op_PhiM = NULL; @@ -2392,7 +2379,6 @@ void firm_init_stat(unsigned enable_options) status->op_MulC = NULL; status->op_DivC = NULL; status->op_ModC = NULL; - status->op_QuotC = NULL; } /* if */ /* for Florian: count the Sel depth */ diff --git a/ir/stat/firmstat_t.h b/ir/stat/firmstat_t.h index c63e18853..3ddeb6fb4 100644 --- a/ir/stat/firmstat_t.h +++ b/ir/stat/firmstat_t.h @@ -329,7 +329,6 @@ typedef struct statistic_info_t { ir_op *op_MulC; /**< pseudo op for multiplication by const */ ir_op *op_DivC; /**< pseudo op for division by const */ ir_op *op_ModC; /**< pseudo op for modulo by const */ - ir_op *op_QuotC; /**< pseudo op for floating point division by const */ ir_op *op_SelSel; /**< pseudo op for Sel(Sel) */ ir_op *op_SelSelSel; /**< pseudo op for Sel(Sel(Sel)) */ dumper_t *dumper; /**< list of dumper */ diff --git a/ir/tv/tv.c b/ir/tv/tv.c index 301da614e..9c821badb 100644 --- a/ir/tv/tv.c +++ b/ir/tv/tv.c @@ -1215,46 +1215,34 @@ ir_tarval *tarval_mul(ir_tarval *a, ir_tarval *b) } /* - * floating point division - */ -ir_tarval *tarval_quo(ir_tarval *a, ir_tarval *b) -{ - assert((a->mode == b->mode) && mode_is_float(a->mode)); - - carry_flag = -1; - - if (no_float) - return tarval_bad; - - if (get_mode_n_vector_elems(a->mode) > 1) { - /* vector arithmetic not implemented yet */ - return tarval_bad; - } - - fc_div((const fp_value*) a->value, (const fp_value*) b->value, NULL); - return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode); -} - -/* - * integer division + * division * overflow is impossible, but look out for division by zero */ ir_tarval *tarval_div(ir_tarval *a, ir_tarval *b) { - assert((a->mode == b->mode) && mode_is_int(a->mode)); + ir_mode *mode = a->mode; + assert(mode == b->mode); carry_flag = -1; - if (get_mode_n_vector_elems(a->mode) > 1) { + if (get_mode_n_vector_elems(mode) > 1) { /* vector arithmetic not implemented yet */ return tarval_bad; } - /* x/0 error */ - if (b == get_mode_null(b->mode)) return tarval_bad; - /* modes of a,b are equal */ - sc_div(a->value, b->value, NULL); - return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode); + if (mode_is_int(mode)) { + /* x/0 error */ + if (b == get_mode_null(mode)) + return tarval_bad; + + /* modes of a,b are equal */ + sc_div(a->value, b->value, NULL); + return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode); + } else { + assert(mode_is_float(mode)); + fc_div((const fp_value*) a->value, (const fp_value*) b->value, NULL); + return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), mode); + } } /* diff --git a/scripts/ir_spec.py b/scripts/ir_spec.py index aacf9d864..9296d8449 100755 --- a/scripts/ir_spec.py +++ b/scripts/ir_spec.py @@ -446,7 +446,7 @@ class CopyB(Op): pinned_init = "op_pin_state_pinned" class Div(Op): - """returns the quotient of its 2 operands, integer version""" + """returns the quotient of its 2 operands""" ins = [ ("mem", "memory dependency"), ("left", "first operand"), @@ -738,33 +738,6 @@ class Proj(Op): ] attr_struct = "proj_attr" -class Quot(Op): - """returns the quotient of its 2 operands, floatingpoint version""" - ins = [ - ("mem", "memory dependency"), - ("left", "first operand"), - ("right", "second operand"), - ] - outs = [ - ("M", "memory result", "pn_Generic_M"), - ("X_regular", "control flow when no exception occurs", "pn_Generic_X_regular"), - ("X_except", "control flow when exception occured", "pn_Generic_X_except"), - ("res", "result of computation", "pn_Generic_other"), - ] - flags = [ "fragile", "uses_memory" ] - attrs_name = "divmod" - attrs = [ - dict( - type = "ir_mode*", - name = "resmode", - comment = "mode of the result value", - ), - ] - attr_struct = "divmod_attr" - pinned = "exception" - op_index = 1 - arity_override = "oparity_binary" - class Raise(Op): """Raises an exception. Unconditional change of control flow. Writes an explicit Except variable to memory to pass it to the exception handler. -- 2.20.1