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][RFC] Teach tree-loop-im to rewrite (A >> B) & 1


On 4/22/07, Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz> wrote:
Hello,

> > Right, this is only equal if we compare the result with zero in a COND_EXPR.
> > I'll add code to verify that and split the transformation out in extra
> > functions.
>
> Here is it.  Bootstrapped and tested on x86_64-unknown-linux-gnu.  Is
> this ok with you?

yes, but see the comments below.  IMHO it would also be cleaner to move all
the tests (TREE_CODE (rhs) == ... and so on) into rewrite_reciprocal and
rewrite_bittest, and perhaps extend the comments a bit, but I may do
that in a followup patch.

Ok - that would always dispatch to the functions which I usually try to avoid. I'll leave that for you in that case.

> +   /* Get at the operands of the shift.  The rhs is TMP1 & 1.  */
> +   stmt1 = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 0));
> +   if (TREE_CODE (stmt1) != GIMPLE_MODIFY_STMT)
> +     return stmt;
> +
> +   /* From TMP1 get to the right shift.  There is a conversion inbetween
> +      possibly inserted by fold.  */
> +   t = GIMPLE_STMT_OPERAND (stmt1, 1);
> +   if (TREE_CODE (t) == NOP_EXPR
> +       || TREE_CODE (t) == CONVERT_EXPR)
> +     t = TREE_OPERAND (t, 0);
> +   if (TREE_CODE (t) != SSA_NAME
> +       || !has_single_use (t))
> +     return stmt;

this seems to match only the code

x = a >> b;
y = (cast) x;
z = y & 1;

however it would fail for

x = a >> b;
z = x & 1;

?

Hm, you are right. It doesn't work the way I intended - I'll add a second testcase where we don't have the cast and make it work. Thanks for noticing ;)

> +   /* Get STMT1, the statement with the A >> B rhs.  */
> +   stmt1 = SSA_NAME_DEF_STMT (t);
> +   if (TREE_CODE (stmt1) != GIMPLE_MODIFY_STMT)
> +     return stmt;
> +
> +   /* Verify that B is loop invariant but A is not.  Verify that with
> +      all the stmt walking we are still in the same loop.  */
> +   t = GIMPLE_STMT_OPERAND (stmt1, 1);
> +   if (TREE_CODE (t) == RSHIFT_EXPR
> +       && loop_containing_stmt (stmt1) == loop_containing_stmt (stmt)
> +       && outermost_invariant_loop_expr (TREE_OPERAND (t, 1),
> +                                         loop_containing_stmt (stmt1)) != NULL
> +       && outermost_invariant_loop_expr (TREE_OPERAND (t, 0),
> +                                         loop_containing_stmt (stmt1)) == NULL)
> +     {
> +       tree a = TREE_OPERAND (t, 0);
> +       tree b = TREE_OPERAND (t, 1);
> +
> +       /* 1 << B */
> +       var = create_tmp_var (TREE_TYPE (a), "shifttmp");
> +       add_referenced_var (var);
> +       t = fold_build2 (LSHIFT_EXPR, TREE_TYPE (a),
> +                    integer_one_node, b);

this should probably be build_int_cst (TREE_TYPE (a), 1)

Yes, thanks.


Richard.


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