From: Dorit Nuzman Date: Wed, 18 Apr 2007 07:55:34 +0000 (+0000) Subject: tree-vect-analyze.c (process_use): New function. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8cf81ddffd26ef1262e2d93f7232d72b92cd72be;p=platform%2Fupstream%2Fgcc.git tree-vect-analyze.c (process_use): New function. * tree-vect-analyze.c (process_use): New function. (vect_mark_stmts_to_be_vectorized): Factor out code to process_use. Check phis in all bbs. * tree-vectorizer.c (vect_is_simple_use): Remove a no longer relavant assert. From-SVN: r123943 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 59b83cf..0c19d7e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2007-04-18 Dorit Nuzman + + * tree-vect-analyze.c (process_use): New function. + (vect_mark_stmts_to_be_vectorized): Factor out code to process_use. + Check phis in all bbs. + * tree-vectorizer.c (vect_is_simple_use): Remove a no longer relavant + assert. + 2007-04-18 Bernd Schmidt * reload1.c (eliminte_regs_in_insn): Use REG_EQUIV notes the same way diff --git a/gcc/tree-vect-analyze.c b/gcc/tree-vect-analyze.c index c707a02..ea28a2c 100644 --- a/gcc/tree-vect-analyze.c +++ b/gcc/tree-vect-analyze.c @@ -2191,6 +2191,81 @@ vect_stmt_relevant_p (tree stmt, loop_vec_info loop_vinfo, } +/* + Function process_use. + + Inputs: + - a USE in STMT in a loop represented by LOOP_VINFO + - LIVE_P, RELEVANT - enum values to be set in the STMT_VINFO of the stmt + that defined USE. This is dont by calling mark_relevant and passing it + the WORKLIST (to add DEF_STMT to the WORKlist in case itis relevant). + + Outputs: + Generally, LIVE_P and RELEVANT are used to define the liveness and + relevance info of the DEF_STMT of this USE: + STMT_VINFO_LIVE_P (DEF_STMT_info) <-- live_p + STMT_VINFO_RELEVANT (DEF_STMT_info) <-- relevant + Exceptions: + - case 1: If USE is used only for address computations (e.g. array indexing), + which does not need to be directly vectorized, then the liveness/relevance + of the respective DEF_STMT is left unchanged. + - case 2: If STMT is a reduction phi and DEF_STMT is a reduction stmt, we + skip DEF_STMT cause it had already been processed. + + Return true if everyting is as expected. Return false otherwise. */ + +static bool +process_use (tree stmt, tree use, loop_vec_info loop_vinfo, bool live_p, + enum vect_relevant relevant, VEC(tree,heap) **worklist) +{ + struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo); + stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt); + stmt_vec_info dstmt_vinfo; + basic_block def_bb; + tree def, def_stmt; + enum vect_def_type dt; + + /* case 1: we are only interested in uses that need to be vectorized. Uses + that are used for address computation are not considered relevant. */ + if (!exist_non_indexing_operands_for_use_p (use, stmt)) + return true; + + if (!vect_is_simple_use (use, loop_vinfo, &def_stmt, &def, &dt)) + { + if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS)) + fprintf (vect_dump, "not vectorized: unsupported use in stmt."); + return false; + } + + if (!def_stmt || IS_EMPTY_STMT (def_stmt)) + return true; + + def_bb = bb_for_stmt (def_stmt); + if (!flow_bb_inside_loop_p (loop, def_bb)) + return true; + + /* case 2: A reduction phi defining a reduction stmt (DEF_STMT). DEF_STMT + must have already been processed, so we just check that everything is as + expected, and we are done. */ + dstmt_vinfo = vinfo_for_stmt (def_stmt); + if (TREE_CODE (stmt) == PHI_NODE + && STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def + && TREE_CODE (def_stmt) != PHI_NODE + && STMT_VINFO_DEF_TYPE (dstmt_vinfo) == vect_reduction_def) + { + if (STMT_VINFO_IN_PATTERN_P (dstmt_vinfo)) + dstmt_vinfo = vinfo_for_stmt (STMT_VINFO_RELATED_STMT (dstmt_vinfo)); + gcc_assert (STMT_VINFO_RELEVANT (dstmt_vinfo) < vect_used_by_reduction); + gcc_assert (STMT_VINFO_LIVE_P (dstmt_vinfo) + || STMT_VINFO_RELEVANT (dstmt_vinfo) > vect_unused_in_loop); + return true; + } + + vect_mark_relevant (worklist, def_stmt, relevant, live_p); + return true; +} + + /* Function vect_mark_stmts_to_be_vectorized. Not all stmts in the loop need to be vectorized. For example: @@ -2215,17 +2290,14 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo) basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo); unsigned int nbbs = loop->num_nodes; block_stmt_iterator si; - tree stmt, use; + tree stmt; stmt_ann_t ann; - ssa_op_iter iter; unsigned int i; stmt_vec_info stmt_vinfo; basic_block bb; tree phi; bool live_p; enum vect_relevant relevant; - tree def, def_stmt; - enum vect_def_type dt; if (vect_print_dump_info (REPORT_DETAILS)) fprintf (vect_dump, "=== vect_mark_stmts_to_be_vectorized ==="); @@ -2261,99 +2333,82 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo) } } - /* 2. Process_worklist */ - while (VEC_length (tree, worklist) > 0) { - stmt = VEC_pop (tree, worklist); + use_operand_p use_p; + ssa_op_iter iter; + stmt = VEC_pop (tree, worklist); if (vect_print_dump_info (REPORT_DETAILS)) { fprintf (vect_dump, "worklist: examine stmt: "); print_generic_expr (vect_dump, stmt, TDF_SLIM); } - /* Examine the USEs of STMT. For each ssa-name USE that is defined - in the loop, mark the stmt that defines it (DEF_STMT) as - relevant/irrelevant and live/dead according to the liveness and - relevance properties of STMT. - */ - + /* Examine the USEs of STMT. For each USE, mark the stmt that defines it + (DEF_STMT) as relevant/irrelevant and live/dead according to the + liveness and relevance properties of STMT. */ ann = stmt_ann (stmt); stmt_vinfo = vinfo_for_stmt (stmt); - relevant = STMT_VINFO_RELEVANT (stmt_vinfo); live_p = STMT_VINFO_LIVE_P (stmt_vinfo); /* Generally, the liveness and relevance properties of STMT are - propagated to the DEF_STMTs of its USEs: - STMT_VINFO_LIVE_P (DEF_STMT_info) <-- live_p - STMT_VINFO_RELEVANT (DEF_STMT_info) <-- relevant - - Exceptions: - - (case 1) - If USE is used only for address computations (e.g. array indexing), - which does not need to be directly vectorized, then the - liveness/relevance of the respective DEF_STMT is left unchanged. - - (case 2) - If STMT has been identified as defining a reduction variable, then - we want to set liveness/relevance as follows: - STMT_VINFO_LIVE_P (DEF_STMT_info) <-- false - STMT_VINFO_RELEVANT (DEF_STMT_info) <-- vect_used_by_reduction - because even though STMT is classified as live (since it defines a - value that is used across loop iterations) and irrelevant (since it - is not used inside the loop), it will be vectorized, and therefore - the corresponding DEF_STMTs need to marked as relevant. - We distinguish between two kinds of relevant stmts - those that are - used by a reduction computation, and those that are (also) used by - a regular computation. This allows us later on to identify stmts - that are used solely by a reduction, and therefore the order of - the results that they produce does not have to be kept. - */ - - /* case 2.2: */ + propagated as is to the DEF_STMTs of its USEs: + live_p <-- STMT_VINFO_LIVE_P (STMT_VINFO) + relevant <-- STMT_VINFO_RELEVANT (STMT_VINFO) + + One exception is when STMT has been identified as defining a reduction + variable; in this case we set the liveness/relevance as follows: + live_p = false + relevant = vect_used_by_reduction + This is because we distinguish between two kinds of relevant stmts - + those that are used by a reduction computation, and those that are + (also) used by a regular computation. This allows us later on to + identify stmts that are used solely by a reduction, and therefore the + order of the results that they produce does not have to be kept. + + Reduction phis are expected to be used by a reduction stmt; Other + reduction stmts are expected to be unused in the loop. These are the + expected values of "relevant" for reduction phis/stmts in the loop: + + relevance: phi stmt + vect_unused_in_loop ok + vect_used_by_reduction ok + vect_used_in_loop */ + if (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def) - { + { + switch (relevant) + { + case vect_unused_in_loop: + gcc_assert (TREE_CODE (stmt) != PHI_NODE); + break; + case vect_used_by_reduction: + if (TREE_CODE (stmt) == PHI_NODE) + break; + case vect_used_in_loop: + default: + if (vect_print_dump_info (REPORT_DETAILS)) + fprintf (vect_dump, "unsupported use of reduction."); + VEC_free (tree, heap, worklist); + return false; + } relevant = vect_used_by_reduction; - live_p = false; + live_p = false; } - i = 0; - FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE) + FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE) { - if (vect_print_dump_info (REPORT_DETAILS)) + tree op = USE_FROM_PTR (use_p); + if (!process_use (stmt, op, loop_vinfo, live_p, relevant, &worklist)) { - fprintf (vect_dump, "worklist: examine use %d: ", i++); - print_generic_expr (vect_dump, use, TDF_SLIM); - } - - /* case 1: we are only interested in uses that need to be vectorized. - Uses that are used for address computation are not considered - relevant. - */ - if (!exist_non_indexing_operands_for_use_p (use, stmt)) - continue; - - if (!vect_is_simple_use (use, loop_vinfo, &def_stmt, &def, &dt)) - { - if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS)) - fprintf (vect_dump, "not vectorized: unsupported use in stmt."); VEC_free (tree, heap, worklist); return false; - } - - if (!def_stmt || IS_EMPTY_STMT (def_stmt)) - continue; - - bb = bb_for_stmt (def_stmt); - if (!flow_bb_inside_loop_p (loop, bb)) - continue; - vect_mark_relevant (&worklist, def_stmt, relevant, live_p); + } } - } /* while worklist */ + } /* while worklist */ VEC_free (tree, heap, worklist); return true; diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c index b0aedf7..212b584 100644 --- a/gcc/tree-vectorizer.c +++ b/gcc/tree-vectorizer.c @@ -1714,15 +1714,6 @@ vect_is_simple_use (tree operand, loop_vec_info loop_vinfo, tree *def_stmt, return false; } - /* stmts inside the loop that have been identified as performing - a reduction operation cannot have uses in the loop. */ - if (*dt == vect_reduction_def && TREE_CODE (*def_stmt) != PHI_NODE) - { - if (vect_print_dump_info (REPORT_DETAILS)) - fprintf (vect_dump, "reduction used in loop."); - return false; - } - if (vect_print_dump_info (REPORT_DETAILS)) fprintf (vect_dump, "type of def: %d.",*dt); @@ -1731,12 +1722,11 @@ vect_is_simple_use (tree operand, loop_vec_info loop_vinfo, tree *def_stmt, case PHI_NODE: *def = PHI_RESULT (*def_stmt); gcc_assert (*dt == vect_induction_def || *dt == vect_reduction_def - || *dt == vect_invariant_def); + || *dt == vect_invariant_def); break; case GIMPLE_MODIFY_STMT: *def = GIMPLE_STMT_OPERAND (*def_stmt, 0); - gcc_assert (*dt == vect_loop_def || *dt == vect_invariant_def); break; default: