On 12 October 2011 17:54, Jakub Jelinek <ja...@redhat.com> wrote:
> Hi!

Hi,

>
> This patch allows vectorization of some loops that use
> bool (which is especially important now that we use bool more often
> even for stmts that weren't originally using bool in the sources),
> in particular (when bool is cast to an integer type, and the bool rhs
> has def stmts within the loop as either BIT_{AND,IOR,XOR}_EXPR,
> or just SSA_NAME assigns or bool -> another bool casts, or comparisons
> (tested recursively).  In that case the pattern recognizer transforms
> the comparisons into COND_EXPRs using suitable integer type (the same width
> as the comparison operands) and other bools to suitable integer types
> with casts added where needed.
>
> The patch doesn't yet handle vectorization of storing into a bool array,
> I'll work on that later.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux.  Ok for trunk?

OK with:

> +
> +/* Helper function of adjust_bool_pattern.  Add a cast to TYPE to a previous
> +   stmt (SSA_NAME_DEF_STMT of VAR), but moving the COND_EXPR from 
> RELATED_STMT

by moving?

> +   to PATTERN_DEF_STMT and adding a cast as RELATED_STMT.  */
> +
> +static tree
> +adjust_bool_pattern_cast (tree type, tree var)
> +{
> +  stmt_vec_info stmt_vinfo = vinfo_for_stmt (SSA_NAME_DEF_STMT (var));
> +  gimple cast_stmt, pattern_stmt;
> +
> +  gcc_assert (!STMT_VINFO_PATTERN_DEF_STMT (stmt_vinfo));
> +  pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_vinfo);
> +  STMT_VINFO_PATTERN_DEF_STMT (stmt_vinfo) = pattern_stmt;
> +  cast_stmt
> +    = gimple_build_assign_with_ops (NOP_EXPR,
> +                                   vect_recog_temp_ssa_var (type, NULL),
> +                                   gimple_assign_lhs (pattern_stmt),
> +                                   NULL_TREE);
> +  STMT_VINFO_RELATED_STMT (stmt_vinfo) = cast_stmt;
> +  return gimple_assign_lhs (cast_stmt);
> +}
> +
> +
> +/* Helper function of vect_recog_bool_pattern.  Do the actual 
> transformations,
> +   recursively.  VAR is an SSA_NAME that should be transformed from bool
> +   to a wider integer type, OUT_TYPE is the desired final integer type of
> +   the whole pattern, TRUEVAL should be NULL unless optimizing
> +   BIT_AND_EXPR into a COND_EXPR with one integer from one of the operands
> +   in the then_clause, STMTS is where statements with added pattern stmts
> +   should be pushed to.  */
> +
> +static tree
> +adjust_bool_pattern (tree var, tree out_type, tree trueval,
> +                    VEC (gimple, heap) **stmts)
> +{
> +  gimple stmt = SSA_NAME_DEF_STMT (var);
> +  enum tree_code rhs_code, def_rhs_code;
> +  tree itype, cond_expr, rhs1, rhs2, irhs1, irhs2;
> +  location_t loc;
> +  gimple pattern_stmt, def_stmt;
> +
> +  rhs1 = gimple_assign_rhs1 (stmt);
> +  rhs2 = gimple_assign_rhs2 (stmt);
> +  rhs_code = gimple_assign_rhs_code (stmt);
> +  loc = gimple_location (stmt);
> +  switch (rhs_code)
> +    {
> +    case SSA_NAME:
> +    CASE_CONVERT:
> +      irhs1 = adjust_bool_pattern (rhs1, out_type, NULL_TREE, stmts);
> +      itype = TREE_TYPE (irhs1);
> +      pattern_stmt
> +       = gimple_build_assign_with_ops (SSA_NAME,
> +                                       vect_recog_temp_ssa_var (itype, NULL),
> +                                       irhs1, NULL_TREE);
> +      break;
> +
> +    case BIT_NOT_EXPR:
> +      irhs1 = adjust_bool_pattern (rhs1, out_type, NULL_TREE, stmts);
> +      itype = TREE_TYPE (irhs1);
> +      pattern_stmt
> +       = gimple_build_assign_with_ops (BIT_XOR_EXPR,
> +                                       vect_recog_temp_ssa_var (itype, NULL),
> +                                       irhs1, build_int_cst (itype, 1));
> +      break;
> +
> +    case BIT_AND_EXPR:
> +      /* Try to optimize x = y & (a < b ? 1 : 0); into
> +        x = (a < b ? y : 0);  */

Could you please add some more explanations here? I found it very
difficult to follow. It would be nice to have an example here (similar
to vect_recog_bool_pattern) to illustrate what these statements and
operands are.


> +      def_stmt = SSA_NAME_DEF_STMT (rhs2);
> +      def_rhs_code = gimple_assign_rhs_code (def_stmt);
> +      if (TREE_CODE_CLASS (def_rhs_code) == tcc_comparison)
> +       {
> +         tree def_rhs1 = gimple_assign_rhs1 (def_stmt);
> +         irhs1 = adjust_bool_pattern (rhs1, out_type, NULL_TREE, stmts);
> +         if (TYPE_PRECISION (TREE_TYPE (irhs1))
> +             == GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (def_rhs1))))
> +           {
> +             gimple tstmt;
> +             stmt_vec_info stmt_def_vinfo = vinfo_for_stmt (def_stmt);
> +             irhs2 = adjust_bool_pattern (rhs2, out_type, irhs1, stmts);
> +             tstmt = VEC_pop (gimple, *stmts);
> +             gcc_assert (tstmt == def_stmt);
> +             VEC_quick_push (gimple, *stmts, stmt);
> +             STMT_VINFO_RELATED_STMT (vinfo_for_stmt (stmt))
> +               = STMT_VINFO_RELATED_STMT (stmt_def_vinfo);
> +             gcc_assert (!STMT_VINFO_PATTERN_DEF_STMT (stmt_def_vinfo));
> +             STMT_VINFO_RELATED_STMT (stmt_def_vinfo) = NULL;
> +             return irhs2;
> +           }
> +         else
> +           irhs2 = adjust_bool_pattern (rhs2, out_type, NULL_TREE, stmts);
> +         goto and_ior_xor;
> +       }
> +      def_stmt = SSA_NAME_DEF_STMT (rhs1);
> +      def_rhs_code = gimple_assign_rhs_code (def_stmt);
> +      if (TREE_CODE_CLASS (def_rhs_code) == tcc_comparison)
> +       {
> +         tree def_rhs1 = gimple_assign_rhs1 (def_stmt);
> +         irhs2 = adjust_bool_pattern (rhs2, out_type, NULL_TREE, stmts);
> +         if (TYPE_PRECISION (TREE_TYPE (irhs2))
> +             == GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (def_rhs1))))
> +           {
> +             gimple tstmt;
> +             stmt_vec_info stmt_def_vinfo = vinfo_for_stmt (def_stmt);
> +             irhs1 = adjust_bool_pattern (rhs1, out_type, irhs2, stmts);
> +             tstmt = VEC_pop (gimple, *stmts);
> +             gcc_assert (tstmt == def_stmt);
> +             VEC_quick_push (gimple, *stmts, stmt);
> +             STMT_VINFO_RELATED_STMT (vinfo_for_stmt (stmt))
> +               = STMT_VINFO_RELATED_STMT (stmt_def_vinfo);
> +             gcc_assert (!STMT_VINFO_PATTERN_DEF_STMT (stmt_def_vinfo));
> +             STMT_VINFO_RELATED_STMT (stmt_def_vinfo) = NULL;
> +             return irhs1;
> +           }
> +         else
> +           irhs1 = adjust_bool_pattern (rhs1, out_type, NULL_TREE, stmts);
> +         goto and_ior_xor;
> +       }
> +      /* FALLTHRU */

Thanks,
Ira

Reply via email to