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
This commit is contained in:
parent
7b715e2e18
commit
8cf81ddffd
3 changed files with 136 additions and 83 deletions
|
@ -1,3 +1,11 @@
|
|||
2007-04-18 Dorit Nuzman <dorit@il.ibm.com>
|
||||
|
||||
* 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 <bernd.schmidt@analog.com>
|
||||
|
||||
* reload1.c (eliminte_regs_in_insn): Use REG_EQUIV notes the same way
|
||||
|
|
|
@ -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
|
||||
propagated as is to the DEF_STMTs of its USEs:
|
||||
live_p <-- STMT_VINFO_LIVE_P (STMT_VINFO)
|
||||
relevant <-- STMT_VINFO_RELEVANT (STMT_VINFO)
|
||||
|
||||
Exceptions:
|
||||
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.
|
||||
|
||||
(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.
|
||||
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:
|
||||
|
||||
(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.
|
||||
*/
|
||||
relevance: phi stmt
|
||||
vect_unused_in_loop ok
|
||||
vect_used_by_reduction ok
|
||||
vect_used_in_loop */
|
||||
|
||||
/* case 2.2: */
|
||||
if (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def)
|
||||
{
|
||||
relevant = vect_used_by_reduction;
|
||||
live_p = false;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
|
||||
{
|
||||
if (vect_print_dump_info (REPORT_DETAILS))
|
||||
{
|
||||
switch (relevant)
|
||||
{
|
||||
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.");
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
relevant = vect_used_by_reduction;
|
||||
live_p = false;
|
||||
}
|
||||
} /* while worklist */
|
||||
|
||||
FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE)
|
||||
{
|
||||
tree op = USE_FROM_PTR (use_p);
|
||||
if (!process_use (stmt, op, loop_vinfo, live_p, relevant, &worklist))
|
||||
{
|
||||
VEC_free (tree, heap, worklist);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} /* while worklist */
|
||||
|
||||
VEC_free (tree, heap, worklist);
|
||||
return true;
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Add table
Reference in a new issue