On Wed, Nov 12, 2014 at 2:54 PM, Yuri Rumyantsev <ysrum...@gmail.com> wrote: > Hi All, > > Here is the last part of patch which is related to vectorization > improvements, namely > > 1. New sub-phase is added which delete dead predicate computations > (such code can prevent loop vectorization since dead computation are > not part of bool pattern tree). It is invoked only under > FLAG_FORCE_VECTORIZE. > 2. New sub-phase is added to provide single uses in tree correspondent > to bool pattern (it takes place when the same predicate is used for > PHI-node predication and predicated memory access through 'mask'). To > do it some code replication is used. It is invoked only under > FLAG_FORCE_VECTORIZE. > 3. I added simple optimization for predicate_mem_writes - do not > generate new mask if it has been produced for given size. > 4. simple change was made in fold_build_cond_expr to simplify > predicate of kind r != 0 where r has boolean type to simply 'r' which > is accepted by bool pattern recognition.
Ick :/ In ifcvt_split_def_stmt I wonder why you copy the use_stmt as well? >From the description it sounds like you want to copy def only. Then, + /* Change one use of var to lhs. */ + FOR_EACH_IMM_USE_FAST (use_p, imm_iter, var) + { + use_stmt = USE_STMT (use_p); + break; + } I would think this should be simply SET_USE (use_p, lhs); break; in stead of copying the stmt, adding it and then removing the "old". What am I missing? The "retry" code also looks odd - why do you walk the BB multiple times instead of just doing sth like while (!has_single_use (lhs)) { gimple copy = ifcvt_split_def_stmt (def_stmt); ifcvt_walk_pattern_tree (copy); } thus returning the copy you create and re-process it (the copy should now have a single-use). I think it would be nice to re-use some utility from tree-vect-patterns.c for stmt_is_root_of_bool_pattern. +/* Delete redundant statements produced by predication which prevents + loop vectorization. */ + +static void +ifcvt_local_dce (basic_block bb) +{ ... + /* Propagate liveness through arguments of live stmt. */ + while (worklist.length () > 0) + { + stmt = worklist.pop (); + code = gimple_code (stmt); + if (gimple_code (stmt) == GIMPLE_PHI) + { + for (i = 0; i < gimple_phi_num_args (stmt); i++) + { + tree arg = PHI_ARG_DEF (stmt, i); + if (TREE_CODE (arg) == SSA_NAME) You can use FOR_EACH_PHI_OR_STMT_USE (but watch out for non-SSA name "uses" then). + /* Delete dead statements. */ + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple_stmt_iterator stmt_it; + + stmt = gsi_stmt (gsi); + if (gimple_plf (stmt, GF_PLF_2)) + { + gimple_set_plf (stmt, GF_PLF_2, false); + continue; no need to clear pass-local flags. You can't assume they are not set at the start of your pass. + stmt_it = gsi_for_stmt (stmt); err - simply use 'gsi' and do the gsi_next () only in the case of GF_PLF_2. The patchset doesn't seem to have any testcases - I'd like to see some that exercise all cases you add handling for. Richard. > ChangeLog: > > 2014-11-12 Yuri Rumyantsev <ysrum...@gmail.com> > > * tree-if-conv.c (fold_build_cond_expr): Add conversion COND to > SSA_NAME if it is comparison r != 0 and r has boolean type. > (predicate_mem_writes): Introduce mask_vec to save mask correspondent > to given size. Do not generate new mask if it exists for given size. > (ifcvt_split_def_stmt): New function. > (ifcvt_walk_pattern_tree): New function. > (stmt_is_root_of_bool_pattern): New function. > (ifcvt_repair_bool_pattern): New function. > (ifcvt_local_dce): New function. > (tree_if_conversion): Add calls of ifcvt_local_dce and > ifcvt_repair_bool_pattern if FLAG_FORCE_VECTORIZE is true.