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