Commit 8cf81ddf by Dorit Nuzman Committed by Dorit Nuzman

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
parent 7b715e2e
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
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;
......
......@@ -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:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment