/* Loop Vectorization
- Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
Contributed by Dorit Naishlos <dorit@il.ibm.com>
This file is part of GCC.
DR_GROUP_STORE_COUNT (res) = 0;
DR_GROUP_GAP (res) = 0;
DR_GROUP_SAME_DR_STMT (res) = NULL_TREE;
+ DR_GROUP_READ_WRITE_DEPENDENCE (res) = false;
return res;
}
return false;
}
- if (*dt == vect_induction_def)
- {
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "induction not supported.");
- return false;
- }
-
return true;
}
int op_type;
tree operation, op1, op2;
tree type;
+ int nloop_uses;
+ tree name;
+ imm_use_iterator imm_iter;
+ use_operand_p use_p;
- if (TREE_CODE (loop_arg) != SSA_NAME)
+ name = PHI_RESULT (phi);
+ nloop_uses = 0;
+ FOR_EACH_IMM_USE_FAST (use_p, imm_iter, name)
{
- if (vect_print_dump_info (REPORT_DETAILS))
+ tree use_stmt = USE_STMT (use_p);
+ if (flow_bb_inside_loop_p (loop, bb_for_stmt (use_stmt))
+ && vinfo_for_stmt (use_stmt)
+ && !is_pattern_stmt_p (vinfo_for_stmt (use_stmt)))
+ nloop_uses++;
+ if (nloop_uses > 1)
{
- fprintf (vect_dump, "reduction: not ssa_name: ");
- print_generic_expr (vect_dump, loop_arg, TDF_SLIM);
+ if (vect_print_dump_info (REPORT_DETAILS))
+ fprintf (vect_dump, "reduction used in loop.");
+ return NULL_TREE;
}
+ }
+
+ if (TREE_CODE (loop_arg) != SSA_NAME)
+ {
+ if (vect_print_dump_info (REPORT_DETAILS))
+ {
+ fprintf (vect_dump, "reduction: not ssa_name: ");
+ print_generic_expr (vect_dump, loop_arg, TDF_SLIM);
+ }
return NULL_TREE;
}
if (!def_stmt)
{
if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "reduction: no def_stmt.");
+ fprintf (vect_dump, "reduction: no def_stmt.");
return NULL_TREE;
}
if (TREE_CODE (def_stmt) != GIMPLE_MODIFY_STMT)
{
if (vect_print_dump_info (REPORT_DETAILS))
- {
- print_generic_expr (vect_dump, def_stmt, TDF_SLIM);
- }
+ print_generic_expr (vect_dump, def_stmt, TDF_SLIM);
return NULL_TREE;
}
+ name = GIMPLE_STMT_OPERAND (def_stmt, 0);
+ nloop_uses = 0;
+ FOR_EACH_IMM_USE_FAST (use_p, imm_iter, name)
+ {
+ tree use_stmt = USE_STMT (use_p);
+ if (flow_bb_inside_loop_p (loop, bb_for_stmt (use_stmt))
+ && vinfo_for_stmt (use_stmt)
+ && !is_pattern_stmt_p (vinfo_for_stmt (use_stmt)))
+ nloop_uses++;
+ if (nloop_uses > 1)
+ {
+ if (vect_print_dump_info (REPORT_DETAILS))
+ fprintf (vect_dump, "reduction used in loop.");
+ return NULL_TREE;
+ }
+ }
+
operation = GIMPLE_STMT_OPERAND (def_stmt, 1);
code = TREE_CODE (operation);
if (!commutative_tree_code (code) || !associative_tree_code (code))
return NULL_TREE;
}
- op_type = TREE_CODE_LENGTH (code);
+ op_type = TREE_OPERAND_LENGTH (operation);
if (op_type != binary_op)
{
if (vect_print_dump_info (REPORT_DETAILS))
}
return NULL_TREE;
}
- else if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type) && flag_trapv)
+ else if (INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_TRAPS (type))
{
/* Changing the order of operations changes the semantics. */
if (vect_print_dump_info (REPORT_DETAILS))
*/
def1 = SSA_NAME_DEF_STMT (op1);
def2 = SSA_NAME_DEF_STMT (op2);
- if (!def1 || !def2)
+ if (!def1 || !def2 || IS_EMPTY_STMT (def1) || IS_EMPTY_STMT (def2))
{
if (vect_print_dump_info (REPORT_DETAILS))
{
return NULL_TREE;
}
- if (TREE_CODE (def1) == GIMPLE_MODIFY_STMT
+
+ /* Check that one def is the reduction def, defined by PHI,
+ the other def is either defined in the loop by a GIMPLE_MODIFY_STMT,
+ or it's an induction (defined by some phi node). */
+
+ if (def2 == phi
&& flow_bb_inside_loop_p (loop, bb_for_stmt (def1))
- && def2 == phi)
+ && (TREE_CODE (def1) == GIMPLE_MODIFY_STMT
+ || STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def1)) == vect_induction_def))
{
if (vect_print_dump_info (REPORT_DETAILS))
{
}
return def_stmt;
}
- else if (TREE_CODE (def2) == GIMPLE_MODIFY_STMT
- && flow_bb_inside_loop_p (loop, bb_for_stmt (def2))
- && def1 == phi)
+ else if (def1 == phi
+ && flow_bb_inside_loop_p (loop, bb_for_stmt (def2))
+ && (TREE_CODE (def2) == GIMPLE_MODIFY_STMT
+ || STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def2)) == vect_induction_def))
{
/* Swap operands (just for simplicity - so that the rest of the code
can assume that the reduction variable is always the last (second)
{
tree init_expr;
tree step_expr;
-
tree evolution_part = evolution_part_in_loop_num (access_fn, loop_nb);
/* When there is no evolution in this loop, the evolution function
return false;
step_expr = evolution_part;
- init_expr = unshare_expr (initial_condition_in_loop_num (access_fn,
- loop_nb));
+ init_expr = unshare_expr (initial_condition_in_loop_num (access_fn, loop_nb));
if (vect_print_dump_info (REPORT_DETAILS))
{
*step = step_expr;
if (TREE_CODE (step_expr) != INTEGER_CST)
- {
+ {
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "step unknown.");
return false;
than all previously defined loops. This fact allows us to run
only over initial loops skipping newly generated ones. */
vect_loops_num = number_of_loops ();
- FOR_EACH_LOOP (li, loop, LI_ONLY_OLD)
+ FOR_EACH_LOOP (li, loop, 0)
{
loop_vec_info loop_vinfo;