This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch] PR 32283


On Wed, Nov 19, 2008 at 5:18 PM, Zdenek Dvorak <rakdver@kam.mff.cuni.cz> wrote:
> Hi,
>
>> > this transformation is different from the one needed (this piece of
>> > code is turning ((x << 2) - 4) & ~3 to (x << 2) - 4).
>>
>> Oops, yes, the transformation I had in mind is still done (by
>> force_to_mode and simplify_and_const_int) in combine.c only.
>>
>> > However,
>> > implementing the required transformation using nonzero_bits would
>> > indeed be a better idea,
>>
>> Good, thanks.
>
> here is the new version.  I kept the transformation (x-4) & 3 -> x & 3
> (even though it is not necessary to achieve the optimization), as it
> might be useful by itself.

The middle-end parts are ok.

Thanks,
Richard.

> Zdenek
>
> Index: tree-ssa-loop-niter.c
> ===================================================================
> *** tree-ssa-loop-niter.c       (revision 141981)
> --- tree-ssa-loop-niter.c       (working copy)
> *************** scev_probably_wraps_p (tree base, tree s
> *** 3053,3059 ****
>
>    /* If we can use the fact that signed and pointer arithmetics does not
>       wrap, we are done.  */
> !   if (use_overflow_semantics && nowrap_type_p (type))
>      return false;
>
>    /* To be able to use estimates on number of iterations of the loop,
> --- 3053,3059 ----
>
>    /* If we can use the fact that signed and pointer arithmetics does not
>       wrap, we are done.  */
> !   if (use_overflow_semantics && nowrap_type_p (TREE_TYPE (base)))
>      return false;
>
>    /* To be able to use estimates on number of iterations of the loop,
> Index: tree-ssa-loop-ivopts.c
> ===================================================================
> *** tree-ssa-loop-ivopts.c      (revision 141981)
> --- tree-ssa-loop-ivopts.c      (working copy)
> *************** rewrite_use_compare (struct ivopts_data
> *** 5323,5333 ****
>      {
>        tree var = var_at_stmt (data->current_loop, cand, use->stmt);
>        tree var_type = TREE_TYPE (var);
>
>        compare = iv_elimination_compare (data, use);
>        bound = unshare_expr (fold_convert (var_type, bound));
> !       op = force_gimple_operand_gsi (&bsi, bound, true, NULL_TREE,
> !                                    true, GSI_SAME_STMT);
>
>        gimple_cond_set_lhs (use->stmt, var);
>        gimple_cond_set_code (use->stmt, compare);
> --- 5323,5337 ----
>      {
>        tree var = var_at_stmt (data->current_loop, cand, use->stmt);
>        tree var_type = TREE_TYPE (var);
> +       gimple_seq stmts;
>
>        compare = iv_elimination_compare (data, use);
>        bound = unshare_expr (fold_convert (var_type, bound));
> !       op = force_gimple_operand (bound, &stmts, true, NULL_TREE);
> !       if (stmts)
> !       gsi_insert_seq_on_edge_immediate (
> !               loop_preheader_edge (data->current_loop),
> !               stmts);
>
>        gimple_cond_set_lhs (use->stmt, var);
>        gimple_cond_set_code (use->stmt, compare);
> Index: simplify-rtx.c
> ===================================================================
> *** simplify-rtx.c      (revision 141981)
> --- simplify-rtx.c      (working copy)
> *************** simplify_binary_operation_1 (enum rtx_co
> *** 2304,2315 ****
>      case AND:
>        if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
>        return trueop1;
> -       /* If we are turning off bits already known off in OP0, we need
> -        not do an AND.  */
>        if (GET_CODE (trueop1) == CONST_INT
> !         && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
> !         && (nonzero_bits (trueop0, mode) & ~INTVAL (trueop1)) == 0)
> !       return op0;
>        if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
>          && GET_MODE_CLASS (mode) != MODE_CC)
>        return op0;
> --- 2304,2322 ----
>      case AND:
>        if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
>        return trueop1;
>        if (GET_CODE (trueop1) == CONST_INT
> !         && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
> !       {
> !         HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, mode);
> !         HOST_WIDE_INT val1 = INTVAL (trueop1);
> !         /* If we are turning off bits already known off in OP0, we need
> !            not do an AND.  */
> !         if ((nzop0 & ~val1) == 0)
> !           return op0;
> !         /* If we are clearing all the nonzero bits, the result is zero.  */
> !         if ((val1 & nzop0) == 0 && !side_effects_p (op0))
> !           return CONST0_RTX (mode);
> !       }
>        if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
>          && GET_MODE_CLASS (mode) != MODE_CC)
>        return op0;
> *************** simplify_binary_operation_1 (enum rtx_co
> *** 2391,2397 ****
>         ((A & N) + B) & M -> (A + B) & M
>         Similarly if (N & M) == 0,
>         ((A | N) + B) & M -> (A + B) & M
> !        and for - instead of + and/or ^ instead of |.  */
>        if (GET_CODE (trueop1) == CONST_INT
>          && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
>          && ~INTVAL (trueop1)
> --- 2398,2406 ----
>         ((A & N) + B) & M -> (A + B) & M
>         Similarly if (N & M) == 0,
>         ((A | N) + B) & M -> (A + B) & M
> !        and for - instead of + and/or ^ instead of |.
> !          Also, if (N & M) == 0, then
> !        (A +- N) & M -> A & M.  */
>        if (GET_CODE (trueop1) == CONST_INT
>          && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
>          && ~INTVAL (trueop1)
> *************** simplify_binary_operation_1 (enum rtx_co
> *** 2404,2409 ****
> --- 2413,2422 ----
>          pmop[0] = XEXP (op0, 0);
>          pmop[1] = XEXP (op0, 1);
>
> +         if (GET_CODE (pmop[1]) == CONST_INT
> +             && (INTVAL (pmop[1]) & INTVAL (trueop1)) == 0)
> +           return simplify_gen_binary (AND, mode, pmop[0], op1);
> +
>          for (which = 0; which < 2; which++)
>            {
>              tem = pmop[which];
> *************** simplify_plus_minus (enum rtx_code code,
> *** 3591,3600 ****
>            ops[j + 1] = save;
>          }
>
> -       /* This is only useful the first time through.  */
> -       if (!canonicalized)
> -         return NULL_RTX;
> -
>        changed = 0;
>        for (i = n_ops - 1; i > 0; i--)
>        for (j = i - 1; j >= 0; j--)
> --- 3604,3609 ----
> *************** simplify_plus_minus (enum rtx_code code,
> *** 3650,3659 ****
> --- 3659,3673 ----
>                    ops[i].neg = lneg;
>                    ops[j].op = NULL_RTX;
>                    changed = 1;
> +                   canonicalized = 1;
>                  }
>              }
>          }
>
> +       /* If nothing changed, fail.  */
> +       if (!canonicalized)
> +         return NULL_RTX;
> +
>        /* Pack all the operands to the lower-numbered entries.  */
>        for (i = 0, j = 0; j < n_ops; j++)
>          if (ops[j].op)
> Index: loop-iv.c
> ===================================================================
> *** loop-iv.c   (revision 141981)
> --- loop-iv.c   (working copy)
> *************** simple_rhs_p (rtx rhs)
> *** 1337,1349 ****
>      case MINUS:
>        op0 = XEXP (rhs, 0);
>        op1 = XEXP (rhs, 1);
> !       /* Allow reg + const sets only.  */
> !       if (REG_P (op0) && !HARD_REGISTER_P (op0) && CONSTANT_P (op1))
> !       return true;
> !       if (REG_P (op1) && !HARD_REGISTER_P (op1) && CONSTANT_P (op0))
> !       return true;
>
> !       return false;
>
>      default:
>        return false;
> --- 1337,1362 ----
>      case MINUS:
>        op0 = XEXP (rhs, 0);
>        op1 = XEXP (rhs, 1);
> !       /* Allow reg + const and reg + reg.  */
> !       if (!(REG_P (op0) && !HARD_REGISTER_P (op0))
> !         && !CONSTANT_P (op0))
> !       return false;
> !       if (!(REG_P (op1) && !HARD_REGISTER_P (op1))
> !         && !CONSTANT_P (op1))
> !       return false;
>
> !       return true;
> !
> !     case ASHIFT:
> !       op0 = XEXP (rhs, 0);
> !       op1 = XEXP (rhs, 1);
> !       /* Allow reg << const.  */
> !       if (!(REG_P (op0) && !HARD_REGISTER_P (op0)))
> !       return false;
> !       if (!CONSTANT_P (op1))
> !       return false;
> !
> !       return true;
>
>      default:
>        return false;
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]