remove DivMod
authorMatthias Braun <matze@braunis.de>
Wed, 9 Feb 2011 13:55:16 +0000 (13:55 +0000)
committerMatthias Braun <matze@braunis.de>
Wed, 9 Feb 2011 13:55:16 +0000 (13:55 +0000)
[r28345]

21 files changed:
include/libfirm/firmstat.h
include/libfirm/irarch.h
include/libfirm/ircons.h
include/libfirm/irhooks.h
include/libfirm/irnode.h
ir/ana/vrp.c
ir/be/ia32/ia32_transform.c
ir/ir/irarch.c
ir/ir/irdump.c
ir/ir/irnode.c
ir/ir/iropt.c
ir/ir/irtypes.h
ir/ir/irverify.c
ir/lower/lower_dw.c
ir/lower/lower_intrinsics.c
ir/opt/gvn_pre.c
ir/opt/loop.c
ir/opt/opt_ldst.c
ir/stat/firmstat.c
ir/stat/firmstat_t.h
scripts/ir_spec.py

index 9fb3b31..518800c 100644 (file)
@@ -35,7 +35,7 @@
 enum firmstat_options_t {
        FIRMSTAT_ENABLED         = 0x00000001,    /**< enable statistics */
        FIRMSTAT_PATTERN_ENABLED = 0x00000002,    /**< enable pattern calculation */
-       FIRMSTAT_COUNT_STRONG_OP = 0x00000004,    /**< if set, count Mul/Div/Mod/DivMod by constant */
+       FIRMSTAT_COUNT_STRONG_OP = 0x00000004,    /**< if set, count Mul/Div/Mod by constant */
        FIRMSTAT_COUNT_DAG       = 0x00000008,    /**< if set, count DAG statistics */
        FIRMSTAT_COUNT_DELETED   = 0x00000010,    /**< if set, count deleted graphs */
        FIRMSTAT_COUNT_SELS      = 0x00000020,    /**< if set, count Sel(Sel(..)) differently */
index e698621..8492b73 100644 (file)
@@ -140,25 +140,6 @@ FIRM_API ir_node *arch_dep_replace_div_by_const(ir_node *irn);
  */
 FIRM_API ir_node *arch_dep_replace_mod_by_const(ir_node *irn);
 
-/**
- * Replace DivMods with Shifts and Add/Subs and Mulh.
- * This function is driven by the 3 parameters:
- * - allow_mulhu
- * - allow_mulhs
- * - max_bits_for_mulh
- *
- * If irn is a DivMod with a Const, the constant is inspected if it meets the
- * requirements of the variables stated above. If a Shl/Add/Sub/Mulh
- * sequence can be generated that meets these requirements, this expression
- * is returned. In each other case irn is returned unmodified.
- *
- * @param div       After call contains the Firm node div result or NULL.
- * @param mod       After call contains the Firm node mod result or NULL.
- * @param irn       The Firm node to inspect.
- */
-FIRM_API void arch_dep_replace_divmod_by_const(ir_node **div, ir_node **mod,
-                                               ir_node *irn);
-
 #include "end.h"
 
 #endif
index 76594d7..7fee219 100644 (file)
  *    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_DivMod (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);
  *      A tuple containing a memory and a execution for modeling exceptions
  *      and the result of the arithmetic operation.
  *
- *    ir_node *new_DivMod (ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode, op_pin_state state)
- *    ---------------------------------------------------------------------------------------------------
- *
- *    Performs Div and Mod on integer values.
- *
- *    Output:
- *      A tuple containing a memory and a execution for modeling exceptions
- *      and the two result of the arithmetic operations.
- *
  *    ir_node *new_Div (ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode, op_pin_state state)
  *    ------------------------------------------------------------------------------------------------
  *
index 78e91f4..9df478d 100644 (file)
@@ -159,7 +159,7 @@ typedef struct hook_entry {
                /** This hook is called after a Mul was replaced by a series of Shift and Add/Sub operations. */
                void (*_hook_arch_dep_replace_mul_with_shifts)(void *context, ir_node *irn);
 
-               /** This hook is called after a Div/Mod/DivMod by a constant value was replaced. */
+               /** This hook is called after a Div/Mod by a constant value was replaced. */
                void (*_hook_arch_dep_replace_division_by_const)(void *context, ir_node *irn);
 
                /** This hook is called after a new mode was registered. */
index a4cdc87..c142758 100644 (file)
@@ -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, DivMod, Div, Mod, And, Or, Eor, Shl,
+   binops are: Add, Sub, Mul, Quot, 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,13 +619,11 @@ 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, DivMod, Div, Mod, Load, Store, Alloc,
+    of an exception: Call, Quot, 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. */
 FIRM_API ir_node *get_fragile_op_mem(ir_node *node);
-/** Returns the result mode of a Div operation. */
-FIRM_API ir_mode *get_divop_resmod(const ir_node *node);
 
 /** Returns true if the operation is a forking control flow
  *  operation: Cond. */
index 8e51b83..10d1896 100644 (file)
@@ -366,7 +366,7 @@ static int vrp_update_node(ir_node *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_Carry(node) is_Cast(node) is_Cmp(node) is_Cond(node)
-       is_CopyB(node) is_Div(node) is_DivMod(node) is_Dummy(node)
+       is_CopyB(node) is_Div(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)
        is_Mod(node) is_Mul(node) is_Mulh(node) is_Mux(node) is_NoMem(node)
index 1cf1f15..a7ff792 100644 (file)
@@ -1066,8 +1066,14 @@ static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
        match_flags_t        flags = match_commutative;
 
        /* happens for div nodes... */
-       if (mode == mode_T)
-               mode = get_divop_resmod(node);
+       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");
+       }
 
        /* cannot use address mode with long double on x87 */
        if (get_mode_size_bits(mode) <= 64)
@@ -1533,7 +1539,7 @@ static ir_node *create_sex_32_64(dbg_info *dbgi, ir_node *block,
 }
 
 /**
- * Generates an ia32 DivMod with additional infrastructure for the
+ * Generates an ia32 Div with additional infrastructure for the
  * register allocator if needed.
  */
 static ir_node *create_Div(ir_node *node)
@@ -1565,12 +1571,6 @@ static ir_node *create_Div(ir_node *node)
                mem     = get_Mod_mem(node);
                mode    = get_Mod_resmode(node);
                break;
-       case iro_DivMod:
-               op1     = get_DivMod_left(node);
-               op2     = get_DivMod_right(node);
-               mem     = get_DivMod_mem(node);
-               mode    = get_DivMod_resmode(node);
-               break;
        default:
                panic("invalid divmod node %+F", node);
        }
@@ -1621,15 +1621,6 @@ static ir_node *gen_Div(ir_node *node)
        return create_Div(node);
 }
 
-/**
- * Generates an ia32 DivMod.
- */
-static ir_node *gen_DivMod(ir_node *node)
-{
-       return create_Div(node);
-}
-
-
 
 /**
  * Creates an ia32 floating Div.
@@ -4583,9 +4574,9 @@ static ir_node *gen_Proj_Load(ir_node *node)
 }
 
 /**
- * Transform and renumber the Projs from a DivMod like instruction.
+ * Transform and renumber the Projs from a Div or Mod instruction.
  */
-static ir_node *gen_Proj_DivMod(ir_node *node)
+static ir_node *gen_Proj_Div_Mod(ir_node *node)
 {
        ir_node  *block    = be_transform_node(get_nodes_block(node));
        ir_node  *pred     = get_Proj_pred(node);
@@ -4624,28 +4615,11 @@ static ir_node *gen_Proj_DivMod(ir_node *node)
                        break;
                }
                break;
-       case iro_DivMod:
-               switch (proj) {
-               case pn_DivMod_M:
-                       return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Div_M);
-               case pn_DivMod_res_div:
-                       return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_div_res);
-               case pn_DivMod_res_mod:
-                       return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_mod_res);
-               case pn_DivMod_X_regular:
-                       return new_rd_Jmp(dbgi, block);
-               case pn_DivMod_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;
-               }
-               break;
        default:
                break;
        }
 
-       panic("No idea how to transform proj->DivMod");
+       panic("No idea how to transform proj->Div/Mod");
 }
 
 /**
@@ -5625,8 +5599,7 @@ static ir_node *gen_Proj(ir_node *node)
                return gen_Proj_Builtin(node);
        case iro_Div:
        case iro_Mod:
-       case iro_DivMod:
-               return gen_Proj_DivMod(node);
+               return gen_Proj_Div_Mod(node);
        case iro_CopyB:
                return gen_Proj_CopyB(node);
        case iro_Quot:
@@ -5706,7 +5679,6 @@ static void register_transformers(void)
        be_set_transform_function(op_Conv,             gen_Conv);
        be_set_transform_function(op_CopyB,            ia32_gen_CopyB);
        be_set_transform_function(op_Div,              gen_Div);
-       be_set_transform_function(op_DivMod,           gen_DivMod);
        be_set_transform_function(op_Eor,              gen_Eor);
        be_set_transform_function(op_ia32_l_Adc,       gen_ia32_l_Adc);
        be_set_transform_function(op_ia32_l_Add,       gen_ia32_l_Add);
index 1a5e1de..0df9fdb 100644 (file)
@@ -820,7 +820,7 @@ static struct mu magicu(ir_tarval *d)
 /**
  * Build the Mulh replacement code for n / tv.
  *
- * Note that 'div' might be a mod or DivMod operation as well
+ * Note that 'div' might be a Mod operation as well
  */
 static ir_node *replace_div_by_mulh(ir_node *div, ir_tarval *tv)
 {
@@ -1088,111 +1088,3 @@ ir_node *arch_dep_replace_mod_by_const(ir_node *irn)
 
        return res;
 }
-
-/* Replace DivMods with Shifts and Add/Subs and Mulh. */
-void arch_dep_replace_divmod_by_const(ir_node **div, ir_node **mod, ir_node *irn)
-{
-       const ir_settings_arch_dep_t *params = be_get_backend_param()->dep_param;
-       *div = *mod = NULL;
-
-       /* If the architecture dependent optimizations were not initialized
-          or this optimization was not enabled. */
-       if (params == NULL ||
-               ((opts & (arch_dep_div_by_const|arch_dep_mod_by_const)) != (arch_dep_div_by_const|arch_dep_mod_by_const)))
-               return;
-
-       if (is_DivMod(irn)) {
-               ir_node *c = get_DivMod_right(irn);
-               ir_node *block, *left;
-               ir_mode *mode;
-               ir_tarval *tv, *ntv;
-               dbg_info *dbg;
-               int n, bits;
-               int k;
-               int n_flag = 0;
-
-               if (! is_Const(c))
-                       return;
-
-               tv = get_Const_tarval(c);
-
-               /* check for division by zero */
-               if (tarval_is_null(tv))
-                       return;
-
-               left  = get_DivMod_left(irn);
-               mode  = get_irn_mode(left);
-               block = get_irn_n(irn, -1);
-               dbg   = get_irn_dbg_info(irn);
-
-               bits = get_mode_size_bits(mode);
-               n    = (bits + 7) / 8;
-
-               k = -1;
-               if (mode_is_signed(mode)) {
-                       /* for signed divisions, the algorithm works for a / -2^k by negating the result */
-                       ntv = tarval_neg(tv);
-                       n_flag = 1;
-                       k = tv_ld2(ntv, n);
-               }
-
-               if (k < 0) {
-                       n_flag = 0;
-                       k = tv_ld2(tv, n);
-               }
-
-               if (k >= 0) { /* division by 2^k or -2^k */
-                       ir_graph *irg = get_irn_irg(irn);
-                       if (mode_is_signed(mode)) {
-                               ir_node *k_node, *c_k;
-                               ir_node *curr = left;
-
-                               if (k != 1) {
-                                       k_node = new_r_Const_long(irg, mode_Iu, k - 1);
-                                       curr   = new_rd_Shrs(dbg, block, left, k_node, mode);
-                               }
-
-                               k_node = new_r_Const_long(irg, mode_Iu, bits - k);
-                               curr   = new_rd_Shr(dbg, block, curr, k_node, mode);
-
-                               curr   = new_rd_Add(dbg, block, left, curr, mode);
-
-                               c_k    = new_r_Const_long(irg, mode_Iu, k);
-
-                               *div   = new_rd_Shrs(dbg, block, curr, c_k, mode);
-
-                               if (n_flag) { /* negate the div result */
-                                       ir_node *k_node = new_r_Const(irg, get_mode_null(mode));
-                                       *div = new_rd_Sub(dbg, block, k_node, *div, mode);
-                               }
-
-                               k_node = new_r_Const_long(irg, mode, (-1) << k);
-                               curr   = new_rd_And(dbg, block, curr, k_node, mode);
-
-                               *mod   = new_rd_Sub(dbg, block, left, curr, mode);
-                       } else {      /* unsigned case */
-                               ir_node *k_node = new_r_Const_long(irg, mode_Iu, k);
-                               *div   = new_rd_Shr(dbg, block, left, k_node, mode);
-
-                               k_node = new_r_Const_long(irg, mode, (1 << k) - 1);
-                               *mod   = new_rd_And(dbg, block, left, k_node, mode);
-                       }
-               } else {
-                       /* other constant */
-                       if (allow_Mulh(params, mode)) {
-                               ir_node *t;
-
-                               *div = replace_div_by_mulh(irn, tv);
-
-                               t    = new_rd_Mul(dbg, block, *div, c, mode);
-
-                               /* t = arch_dep_mul_to_shift(t); */
-
-                               *mod = new_rd_Sub(dbg, block, left, t, mode);
-                       }
-               }
-       }
-
-       if (*div)
-               hook_arch_dep_replace_division_by_const(irn);
-}
index afc39b5..84b329d 100644 (file)
@@ -724,9 +724,6 @@ void dump_node_opcode(FILE *F, ir_node *n)
        case iro_Mod:
                fprintf(F, "%s[%s]", get_irn_opname(n), get_mode_name_ex(get_Mod_resmode(n), NULL));
                break;
-       case iro_DivMod:
-               fprintf(F, "%s[%s]", get_irn_opname(n), get_mode_name_ex(get_DivMod_resmode(n), NULL));
-               break;
        case iro_Builtin:
                fprintf(F, "%s[%s]", get_irn_opname(n), get_builtin_kind_name(get_Builtin_kind(n)));
                break;
@@ -845,17 +842,6 @@ static const pns_lookup_t quot_lut[] = {
 #undef X
 };
 
-/** the lookup table for Proj(DivMod) names */
-static const pns_lookup_t divmod_lut[] = {
-#define X(a)    { pn_DivMod_##a, #a }
-       X(M),
-       X(X_regular),
-       X(X_except),
-       X(res_div),
-       X(res_mod)
-#undef X
-};
-
 /** the lookup table for Proj(Div) names */
 static const pns_lookup_t div_lut[] = {
 #define X(a)    { pn_Div_##a, #a }
@@ -949,7 +935,6 @@ static const proj_lookup_t proj_lut[] = {
        { iro_Cond,    E(cond_lut) },
        { iro_Call,    E(call_lut) },
        { iro_Quot,    E(quot_lut) },
-       { iro_DivMod,  E(divmod_lut) },
        { iro_Div,     E(div_lut) },
        { iro_Mod,     E(mod_lut) },
        { iro_Load,    E(load_lut) },
index 02e3e26..171b484 100644 (file)
@@ -968,15 +968,6 @@ void set_Sel_index(ir_node *node, int pos, ir_node *index)
        set_irn_n(node, pos + SEL_INDEX_OFFSET, index);
 }
 
-
-/* For unary and binary arithmetic operations the access to the
-   operands can be factored out.  Left is the first, right the
-   second arithmetic value  as listed in tech report 0999-33.
-   unops are: Minus, Abs, Not, Conv, Cast
-   binops are: Add, Sub, Mul, Quot, DivMod, Div, Mod, And, Or, Eor, Shl,
-   Shr, Shrs, Rotate, Cmp */
-
-
 ir_node **get_Call_param_arr(ir_node *node)
 {
        assert(is_Call(node));
@@ -1585,7 +1576,6 @@ ir_node *get_fragile_op_mem(ir_node *node)
        switch (get_irn_opcode(node)) {
        case iro_Call  :
        case iro_Quot  :
-       case iro_DivMod:
        case iro_Div   :
        case iro_Mod   :
        case iro_Load  :
@@ -1602,19 +1592,6 @@ ir_node *get_fragile_op_mem(ir_node *node)
        }
 }
 
-/* Returns the result mode of a Div operation. */
-ir_mode *get_divop_resmod(const ir_node *node)
-{
-       switch (get_irn_opcode(node)) {
-       case iro_Quot  : return get_Quot_resmode(node);
-       case iro_DivMod: return get_DivMod_resmode(node);
-       case iro_Div   : return get_Div_resmode(node);
-       case iro_Mod   : return get_Mod_resmode(node);
-       default:
-               panic("should not be reached");
-       }
-}
-
 /* Returns true if the operation is a forking control flow operation. */
 int (is_irn_forking)(const ir_node *node)
 {
index f72a337..ddea97b 100644 (file)
@@ -593,24 +593,6 @@ static ir_tarval *do_computed_value_Mod(const ir_node *a, const ir_node *b)
        return tarval_bad;
 }  /* do_computed_value_Mod */
 
-/**
- * Return the value of a Proj(DivMod).
- */
-static ir_tarval *computed_value_Proj_DivMod(const ir_node *n)
-{
-       long proj_nr = get_Proj_proj(n);
-
-       /* compute either the Div or the Mod part */
-       if (proj_nr == pn_DivMod_res_div) {
-               const ir_node *a = get_Proj_pred(n);
-               return do_computed_value_Div(get_DivMod_left(a), get_DivMod_right(a));
-       } else if (proj_nr == pn_DivMod_res_mod) {
-               const ir_node *a = get_Proj_pred(n);
-               return do_computed_value_Mod(get_DivMod_left(a), get_DivMod_right(a));
-       }
-       return tarval_bad;
-}  /* computed_value_Proj_DivMod */
-
 /**
  * Return the value of a Proj(Div).
  */
@@ -723,7 +705,6 @@ static ir_op_ops *firm_set_default_computed_value(ir_opcode code, ir_op_ops *ops
        CASE(Mux);
        CASE(Confirm);
        CASE_PROJ(Cmp);
-       CASE_PROJ(DivMod);
        CASE_PROJ(Div);
        CASE_PROJ(Mod);
        CASE_PROJ(Quot);
@@ -1565,40 +1546,6 @@ static ir_node *equivalent_node_Proj_Quot(ir_node *proj)
        return proj;
 }  /* equivalent_node_Proj_Quot */
 
-/**
- * Optimize a / 1 = a.
- */
-static ir_node *equivalent_node_Proj_DivMod(ir_node *proj)
-{
-       ir_node   *oldn   = proj;
-       ir_node   *divmod = get_Proj_pred(proj);
-       ir_node   *b      = get_DivMod_right(divmod);
-       ir_tarval *tb     = value_of(b);
-
-       /* Div is not commutative. */
-       if (tarval_is_one(tb)) { /* div(x, 1) == x */
-               switch (get_Proj_proj(proj)) {
-               case pn_DivMod_M:
-                       proj = get_DivMod_mem(divmod);
-                       DBG_OPT_ALGSIM0(oldn, proj, FS_OPT_NEUTRAL_1);
-                       return proj;
-
-               case pn_DivMod_res_div:
-                       proj = get_DivMod_left(divmod);
-                       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_DivMod().
-                          Note further that the pn_DivMod_res_div case is handled in
-                          computed_value_Proj(). */
-                       return proj;
-               }
-       }
-       return proj;
-}  /* equivalent_node_Proj_DivMod */
-
 /**
  * Optimize CopyB(mem, x, x) into a Nop.
  */
@@ -1949,7 +1896,6 @@ static ir_op_ops *firm_set_default_equivalent_node(ir_opcode code, ir_op_ops *op
        CASE_PROJ(Tuple);
        CASE_PROJ(Div);
        CASE_PROJ(Quot);
-       CASE_PROJ(DivMod);
        CASE_PROJ(CopyB);
        CASE_PROJ(Bound);
        CASE_PROJ(Load);
@@ -3071,121 +3017,6 @@ make_tuple:
        return n;
 }  /* transform_node_Mod */
 
-/**
- * Transform a DivMod node.
- */
-static ir_node *transform_node_DivMod(ir_node *n)
-{
-       const ir_node *dummy;
-       ir_node       *a = get_DivMod_left(n);
-       ir_node       *b = get_DivMod_right(n);
-       ir_mode       *mode = get_DivMod_resmode(n);
-       ir_node       *va, *vb;
-       ir_graph      *irg = get_irn_irg(n);
-       ir_tarval     *ta, *tb;
-       int           evaluated = 0;
-
-       if (is_Const(b) && is_const_Phi(a)) {
-               /* check for Div(Phi, Const) */
-               va = apply_binop_on_phi(a, get_Const_tarval(b), (eval_func) tarval_div, mode, 0);
-               vb = apply_binop_on_phi(a, get_Const_tarval(b), (eval_func) tarval_mod, mode, 0);
-               if (va && vb) {
-                       DBG_OPT_ALGSIM0(n, va, FS_OPT_CONST_PHI);
-                       DBG_OPT_ALGSIM0(n, vb, FS_OPT_CONST_PHI);
-                       goto make_tuple;
-               }
-       }
-       else if (is_Const(a) && is_const_Phi(b)) {
-               /* check for Div(Const, Phi) */
-               va = apply_binop_on_phi(b, get_Const_tarval(a), (eval_func) tarval_div, mode, 1);
-               vb = apply_binop_on_phi(b, get_Const_tarval(a), (eval_func) tarval_mod, mode, 1);
-               if (va && vb) {
-                       DBG_OPT_ALGSIM0(n, va, FS_OPT_CONST_PHI);
-                       DBG_OPT_ALGSIM0(n, vb, FS_OPT_CONST_PHI);
-                       goto make_tuple;
-               }
-       }
-       else if (is_const_Phi(a) && is_const_Phi(b)) {
-               /* check for Div(Phi, Phi) */
-               va = apply_binop_on_2_phis(a, b, (eval_func) tarval_div, mode);
-               vb = apply_binop_on_2_phis(a, b, (eval_func) tarval_mod, mode);
-               if (va && vb) {
-                       DBG_OPT_ALGSIM0(n, va, FS_OPT_CONST_PHI);
-                       DBG_OPT_ALGSIM0(n, vb, FS_OPT_CONST_PHI);
-                       goto make_tuple;
-               }
-       }
-
-       ta = value_of(a);
-       tb = value_of(b);
-       if (tb != tarval_bad) {
-               if (tb == get_mode_one(get_tarval_mode(tb))) {
-                       va = a;
-                       vb = new_r_Const(irg, get_mode_null(mode));
-                       DBG_OPT_CSTEVAL(n, vb);
-                       goto make_tuple;
-               } else if (ta != tarval_bad) {
-                       ir_tarval *resa, *resb;
-                       resa = tarval_div(ta, tb);
-                       if (resa == tarval_bad) return n; /* Causes exception!!! Model by replacing through
-                                                            Jmp for X result!? */
-                       resb = tarval_mod(ta, tb);
-                       if (resb == tarval_bad) return n; /* Causes exception! */
-                       va = new_r_Const(irg, resa);
-                       vb = new_r_Const(irg, resb);
-                       DBG_OPT_CSTEVAL(n, va);
-                       DBG_OPT_CSTEVAL(n, vb);
-                       goto make_tuple;
-               } else if (mode_is_signed(mode) && tb == get_mode_minus_one(mode)) {
-                       va = new_rd_Minus(get_irn_dbg_info(n), get_nodes_block(n), a, mode);
-                       vb = new_r_Const(irg, get_mode_null(mode));
-                       DBG_OPT_CSTEVAL(n, va);
-                       DBG_OPT_CSTEVAL(n, vb);
-                       goto make_tuple;
-               } else { /* Try architecture dependent optimization */
-                       va = a;
-                       vb = b;
-                       arch_dep_replace_divmod_by_const(&va, &vb, n);
-                       evaluated = va != NULL;
-               }
-       } else if (a == b) {
-               if (value_not_zero(a, &dummy)) {
-                       /* a/a && a != 0 */
-                       va = new_r_Const(irg, get_mode_one(mode));
-                       vb = new_r_Const(irg, get_mode_null(mode));
-                       DBG_OPT_CSTEVAL(n, va);
-                       DBG_OPT_CSTEVAL(n, vb);
-                       goto make_tuple;
-               } else {
-                       /* BEWARE: it is NOT possible to optimize a/a to 1, as this may cause a exception */
-                       return n;
-               }
-       } else if (ta == get_mode_null(mode) && value_not_zero(b, &dummy)) {
-               /* 0 / non-Const = 0 */
-               vb = va = a;
-               goto make_tuple;
-       }
-
-       if (evaluated) { /* replace by tuple */
-               ir_node *mem, *blk;
-
-make_tuple:
-               mem = get_DivMod_mem(n);
-               /* skip a potential Pin */
-               mem = skip_Pin(mem);
-
-               blk = get_nodes_block(n);
-               turn_into_tuple(n, pn_DivMod_max);
-               set_Tuple_pred(n, pn_DivMod_M,         mem);
-               set_Tuple_pred(n, pn_DivMod_X_regular, new_r_Jmp(blk));
-               set_Tuple_pred(n, pn_DivMod_X_except,  get_irg_bad(irg)); /*no exception*/
-               set_Tuple_pred(n, pn_DivMod_res_div,   va);
-               set_Tuple_pred(n, pn_DivMod_res_mod,   vb);
-       }
-
-       return n;
-}  /* transform_node_DivMod */
-
 /**
  * Optimize x / c to x * (1/c)
  */
@@ -3977,71 +3808,6 @@ static ir_node *transform_node_Proj_Mod(ir_node *proj)
        return proj;
 }  /* transform_node_Proj_Mod */
 
-/**
- * Transform a Proj(DivMod) with a non-zero value.
- * Removes the exceptions and routes the memory to the NoMem node.
- */
-static ir_node *transform_node_Proj_DivMod(ir_node *proj)
-{
-       ir_node *divmod = get_Proj_pred(proj);
-       ir_node *b      = get_DivMod_right(divmod);
-       ir_node *res, *new_mem;
-       const ir_node *confirm;
-       long proj_nr;
-
-       if (value_not_zero(b, &confirm)) {
-               /* DivMod(x, y) && y != 0 */
-               proj_nr = get_Proj_proj(proj);
-
-               if (confirm == NULL) {
-                       /* we are sure we have a Const != 0 */
-                       new_mem = get_DivMod_mem(divmod);
-                       new_mem = skip_Pin(new_mem);
-                       set_DivMod_mem(divmod, new_mem);
-                       set_irn_pinned(divmod, op_pin_state_floats);
-               }
-
-               switch (proj_nr) {
-
-               case pn_DivMod_X_regular:
-                       return new_r_Jmp(get_nodes_block(divmod));
-
-               case pn_DivMod_X_except: {
-                       /* we found an exception handler, remove it */
-                       ir_graph *irg = get_irn_irg(proj);
-                       DBG_OPT_EXC_REM(proj);
-                       return get_irg_bad(irg);
-               }
-
-               case pn_DivMod_M: {
-                       ir_graph *irg = get_irn_irg(proj);
-                       res = get_DivMod_mem(divmod);
-                       new_mem = get_irg_no_mem(irg);
-
-                       if (confirm) {
-                               /* This node can only float up to the Confirm block */
-                               new_mem = new_r_Pin(get_nodes_block(confirm), new_mem);
-                       }
-                       /* this is a DivMod without exception, we can remove the memory edge */
-                       set_DivMod_mem(divmod, new_mem);
-                       return res;
-               }
-
-               case pn_DivMod_res_mod:
-                       if (get_DivMod_left(divmod) == b) {
-                               /* a % a = 0 if a != 0 */
-                               ir_graph *irg  = get_irn_irg(proj);
-                               ir_mode  *mode = get_irn_mode(proj);
-                               ir_node  *res  = new_r_Const(irg, get_mode_null(mode));
-
-                               DBG_OPT_CSTEVAL(divmod, res);
-                               return res;
-                       }
-               }
-       }
-       return proj;
-}  /* transform_node_Proj_DivMod */
-
 /**
  * Optimizes jump tables (CondIs or CondIu) by removing all impossible cases.
  */
@@ -4735,8 +4501,7 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
        if ((proj_nr == pn_Cmp_Eq || proj_nr == pn_Cmp_Lg) && is_Const(right) && is_Const_null(right) && is_Proj(left)) {
                ir_node *op = get_Proj_pred(left);
 
-               if ((is_Mod(op) && get_Proj_proj(left) == pn_Mod_res) ||
-                   (is_DivMod(op) && get_Proj_proj(left) == pn_DivMod_res_mod)) {
+               if (is_Mod(op) && get_Proj_proj(left) == pn_Mod_res) {
                        ir_node *c = get_binop_right(op);
 
                        if (is_Const(c)) {
@@ -6092,7 +5857,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_PROJ_EX(DivMod);
        CASE(Quot);
        CASE_PROJ_EX(Cmp);
        CASE_PROJ_EX(Cond);
@@ -6259,25 +6023,25 @@ static int node_cmp_attr_Div(ir_node *a, ir_node *b)
                   ma->no_remainder  != mb->no_remainder;
 }  /* node_cmp_attr_Div */
 
-/** Compares the attributes of two DivMod nodes. */
-static int node_cmp_attr_DivMod(ir_node *a, ir_node *b)
+/** Compares the attributes of two Div or Mod nodes. */
+static int node_cmp_attr_Div_Mod(ir_node *a, ir_node *b)
 {
        const divmod_attr *ma = &a->attr.divmod;
        const divmod_attr *mb = &b->attr.divmod;
        return ma->exc.pin_state != mb->exc.pin_state ||
                   ma->resmode       != mb->resmode;
-}  /* node_cmp_attr_DivMod */
+}  /* node_cmp_attr_Div_Mod */
 
 /** Compares the attributes of two Mod nodes. */
 static int node_cmp_attr_Mod(ir_node *a, ir_node *b)
 {
-       return node_cmp_attr_DivMod(a, 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_DivMod(a, b);
+       return node_cmp_attr_Div_Mod(a, b);
 }  /* node_cmp_attr_Quot */
 
 /** Compares the attributes of two Confirm nodes. */
@@ -6381,7 +6145,6 @@ static ir_op_ops *firm_set_default_node_cmp_attr(ir_opcode code, ir_op_ops *ops)
        CASE(Confirm);
        CASE(ASM);
        CASE(Div);
-       CASE(DivMod);
        CASE(Mod);
        CASE(Quot);
        CASE(Bound);
index 6d3e736..2c5340b 100644 (file)
@@ -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/DivMod/Quot attribute. */
+/** Div/Mod/Quot attribute. */
 typedef struct divmod_attr {
        except_attr    exc;           /**< The exception attribute. MUST be the first one. */
        ir_mode        *resmode;      /**< Result mode for the division. */
@@ -336,7 +336,7 @@ typedef union ir_attr {
        copyb_attr     copyb;         /**< For CopyB operation */
        bound_attr     bound;         /**< For Bound operation */
        conv_attr      conv;          /**< For Conv operation */
-       divmod_attr    divmod;        /**< For Div/Mod/DivMod operation */
+       divmod_attr    divmod;        /**< For Div/Mod operation */
        asm_attr       assem;         /**< For ASM operation. */
 } ir_attr;
 
index 0180f87..4df9800 100644 (file)
@@ -465,40 +465,6 @@ static int verify_node_Proj_Quot(ir_node *n, ir_node *p)
        return 1;
 }
 
-/**
- * verify a Proj(DivMod) node
- */
-static int verify_node_Proj_DivMod(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_DivMod_M         && mode == mode_M) ||
-                       (proj == pn_DivMod_X_regular && mode == mode_X) ||
-                       (proj == pn_DivMod_X_except  && mode == mode_X) ||
-                       (proj == pn_DivMod_res_div   && mode_is_int(mode) && mode == get_DivMod_resmode(n)) ||
-                       (proj == pn_DivMod_res_mod   && mode_is_int(mode) && mode == get_DivMod_resmode(n))
-               ),
-               "wrong Proj from DivMod", 0,
-               show_proj_failure(p);
-       );
-       if (proj == pn_DivMod_X_regular)
-               ASSERT_AND_RET(
-                       get_irn_pinned(n) == op_pin_state_pinned,
-                       "Regular Proj from unpinned DivMod", 0);
-       else if (proj == pn_DivMod_X_except)
-               ASSERT_AND_RET(
-                       get_irn_pinned(n) == op_pin_state_pinned,
-                       "Exception Proj from unpinned DivMod", 0);
-       else if (proj == pn_DivMod_M)
-               ASSERT_AND_RET(
-                       get_irn_pinned(n) == op_pin_state_pinned,
-                       "Memory Proj from unpinned DivMod", 0);
-       return 1;
-}
-
 /**
  * verify a Proj(Div) node
  */
@@ -1331,28 +1297,6 @@ static int verify_node_Quot(ir_node *n, ir_graph *irg)
        return 1;
 }
 
-/**
- * verify a DivMod node
- */
-static int verify_node_DivMod(ir_node *n, ir_graph *irg)
-{
-       ir_mode *mymode  = get_irn_mode(n);
-       ir_mode *op1mode = get_irn_mode(get_DivMod_mem(n));
-       ir_mode *op2mode = get_irn_mode(get_DivMod_left(n));
-       ir_mode *op3mode = get_irn_mode(get_DivMod_right(n));
-       (void) irg;
-
-       ASSERT_AND_RET(
-               /* DivMod: BB x M x int x int --> M x X x int x int */
-               op1mode == mode_M &&
-               mode_is_int(op2mode) &&
-               op3mode == op2mode &&
-               mymode == mode_T,
-               "DivMod node", 0
-               );
-       return 1;
-}
-
 /**
  * verify a Div node
  */
@@ -2213,7 +2157,6 @@ void firm_set_default_verifyer(ir_opcode code, ir_op_ops *ops)
        CASE(Mul);
        CASE(Mulh);
        CASE(Quot);
-       CASE(DivMod);
        CASE(Div);
        CASE(Mod);
        CASE(And);
@@ -2254,7 +2197,6 @@ void firm_set_default_verifyer(ir_opcode code, ir_op_ops *ops)
        CASE(InstOf);
        CASE(Call);
        CASE(Quot);
-       CASE(DivMod);
        CASE(Div);
        CASE(Mod);
        CASE(Cmp);
index 243c593..51ee9b7 100644 (file)
@@ -250,8 +250,6 @@ static ir_mode *get_irn_op_mode(ir_node *node)
                return get_Load_mode(node);
        case iro_Store:
                return get_irn_mode(get_Store_value(node));
-       case iro_DivMod:
-               return get_irn_mode(get_DivMod_left(node));
        case iro_Div:
                return get_irn_mode(get_Div_left(node));
        case iro_Mod:
@@ -628,14 +626,6 @@ static void lower_Mod(ir_node *node, ir_mode *mode, lower_env_t *env)
        }
 }
 
-static void lower_DivMod(ir_node *node, ir_mode *mode, lower_env_t *env)
-{
-       (void) node;
-       (void) mode;
-       (void) env;
-       panic("DivMod is deprecated, no doubleword lowering");
-}
-
 /**
  * Translate a binop.
  *
@@ -2366,7 +2356,6 @@ void lower_dw_ops(const lwrdw_param_t *param)
        enter_lower_func(op_Const,   lower_Const);
        enter_lower_func(op_Conv,    lower_Conv);
        enter_lower_func(op_Div,     lower_Div);
-       enter_lower_func(op_DivMod,  lower_DivMod);
        enter_lower_func(op_Eor,     lower_Eor);
        enter_lower_func(op_Load,    lower_Load);
        enter_lower_func(op_Minus,   lower_Unop);
index 82b1504..f78daa8 100644 (file)
@@ -1116,7 +1116,6 @@ static ir_mode *get_irn_res_mode(ir_node *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);
-       case iro_DivMod: return get_DivMod_resmode(node);
        default: return NULL;
        }
 }  /* get_irn_res_mode */
index 9be72d7..f4407fa 100644 (file)
@@ -191,7 +191,7 @@ static int is_nice_value(ir_node *n)
                return 0;
        mode = get_irn_mode(n);
        if (!mode_is_data(mode)) {
-               if (! is_Div(n) && ! is_Mod(n) && ! is_DivMod(n))
+               if (! is_Div(n) && ! is_Mod(n))
                        return 0;
                if (! is_NoMem(get_fragile_op_mem(n)))
                        return 0;
index 2635ced..d1e1a5c 100644 (file)
@@ -1675,7 +1675,7 @@ static void create_duffs_block(void)
        ir_mode *mode;
 
        ir_node *block1, *count_block, *duff_block;
-       ir_node *ems, *ems_divmod, *ems_mod_proj, *cmp_null,
+       ir_node *ems, *ems_mod, *ems_div, *ems_mod_proj, *cmp_null,
                *cmp_proj, *ems_mode_cond, *x_true, *x_false, *const_null;
        ir_node *true_val, *false_val;
        ir_node *ins[2];
@@ -1713,17 +1713,23 @@ static void create_duffs_block(void)
        ems = new_Sub(loop_info.end_val, loop_info.start_val,
                get_irn_mode(loop_info.end_val));
 
-       DB((dbg, LEVEL_4, "divmod ins %N %N\n", ems, loop_info.step));
-       ems_divmod = new_r_DivMod(block1,
+       DB((dbg, LEVEL_4, "mod ins %N %N\n", ems, loop_info.step));
+       ems_mod = new_r_Mod(block1,
+               new_NoMem(),
+               ems,
+               loop_info.step,
+               mode,
+               op_pin_state_pinned);
+       ems_div = new_r_Div(block1,
                new_NoMem(),
                ems,
                loop_info.step,
                mode,
                op_pin_state_pinned);
 
-       DB((dbg, LEVEL_4, "New module node %N\n", ems_divmod));
+       DB((dbg, LEVEL_4, "New module node %N\n", ems_mod));
 
-       ems_mod_proj = new_r_Proj(ems_divmod, mode_Iu, pn_DivMod_res_mod);
+       ems_mod_proj = new_r_Proj(ems_mod, mode_Iu, pn_Mod_res);
        cmp_null = new_r_Cmp(block1, ems_mod_proj, const_null);
        cmp_proj = new_r_Proj(cmp_null, mode_b, pn_Cmp_Eq);
        ems_mode_cond = new_r_Cond(block1, cmp_proj);
@@ -1767,7 +1773,7 @@ static void create_duffs_block(void)
 
        correction = new_r_Phi(count_block, 2, ins, mode);
 
-       count = new_r_Proj(ems_divmod, mode, pn_DivMod_res_div);
+       count = new_r_Proj(ems_div, mode, pn_Div_res);
 
        /* (end - start) / step  +  correction */
        count = new_Add(count, correction, mode);
index 8d312d3..311d683 100644 (file)
@@ -1201,7 +1201,7 @@ static void update_Call_memop(memop_t *m)
 }  /* update_Call_memop */
 
 /**
- * Update a memop for a Div/Mod/Quot/DivMod.
+ * Update a memop for a Div/Mod/Quot.
  *
  * @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_DivMod:
                case iro_Quot:
                case iro_Mod:
                        update_DivOp_memop(op);
index 5e663a9..8dabf65 100644 (file)
@@ -65,9 +65,6 @@ static ir_op _op_DivC;
 /** The Div by Const node. */
 static ir_op _op_ModC;
 
-/** The Div by Const node. */
-static ir_op _op_DivModC;
-
 /** The Quot by Const node. */
 static ir_op _op_QuotC;
 
@@ -593,12 +590,6 @@ static ir_op *stat_get_irn_op(ir_node *node)
                        op = status->op_ModC ? status->op_ModC : op;
                }  /* if */
                break;
-       case iro_DivMod:
-               if (is_Const(get_DivMod_right(node))) {
-                       /* special case, a division/modulo by a const, count on extra counter */
-                       op = status->op_DivModC ? status->op_DivModC : 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 */
@@ -1113,8 +1104,6 @@ static ir_mode *get_irn_op_mode(ir_node *node)
                return get_Load_mode(node);
        case iro_Store:
                return get_irn_mode(get_Store_value(node));
-       case iro_DivMod:
-               return get_irn_mode(get_DivMod_left(node));
        case iro_Div:
                return get_irn_mode(get_Div_left(node));
        case iro_Mod:
@@ -2386,9 +2375,6 @@ void firm_init_stat(unsigned enable_options)
                _op_ModC.code    = --num;
                _op_ModC.name    = new_id_from_chars(X("ModC"));
 
-               _op_DivModC.code = --num;
-               _op_DivModC.name = new_id_from_chars(X("DivModC"));
-
                _op_QuotC.code   = --num;
                _op_QuotC.name   = new_id_from_chars(X("QuotC"));
 
@@ -2398,7 +2384,6 @@ void firm_init_stat(unsigned enable_options)
                status->op_MulC    = &_op_MulC;
                status->op_DivC    = &_op_DivC;
                status->op_ModC    = &_op_ModC;
-               status->op_DivModC = &_op_DivModC;
                status->op_QuotC   = &_op_QuotC;
        } else {
                status->op_Phi0    = NULL;
@@ -2407,7 +2392,6 @@ void firm_init_stat(unsigned enable_options)
                status->op_MulC    = NULL;
                status->op_DivC    = NULL;
                status->op_ModC    = NULL;
-               status->op_DivModC = NULL;
                status->op_QuotC   = NULL;
        }  /* if */
 
index 9195701..c63e188 100644 (file)
@@ -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_DivModC;         /**< pseudo op for DivMod 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)) */
index 4bf7842..aacf9d8 100755 (executable)
@@ -477,34 +477,6 @@ class Div(Op):
        op_index    = 1
        arity_override = "oparity_binary"
 
-class DivMod(Op):
-       """divides its 2 operands and computes the remainder of the division"""
-       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_div",   "result of computation a/b",             "pn_Generic_other"),
-               ("res_mod",   "result of computation a%b"),
-       ]
-       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 Dummy(Op):
        """A placeholder value. This is used when constructing cyclic graphs where
        you have cases where not all predecessors of a phi-node are known. Dummy