diff options
author | dpatel <dpatel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-04-12 01:35:54 +0000 |
---|---|---|
committer | dpatel <dpatel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-04-12 01:35:54 +0000 |
commit | e9705e7fbd8fb3403fd54ded918bc2e649f74ddd (patch) | |
tree | f188986dd14899759aa5d472d21666c8b4c61591 /gcc/tree-vect-transform.c | |
parent | f8b517614769ca972988344b8cd08195e0f15125 (diff) | |
download | gcc-e9705e7fbd8fb3403fd54ded918bc2e649f74ddd.tar.gz |
* tree-data-ref.c (build_classic_dist_vector,
compute_subscript_distance): Make externally visible.
* tree-data-ref.h (build_classic_dist_vector,
compute_subscript_distance): Same.
* tree-vect-analyze.c (vect_analyze_data_ref_dependence):
Check distance vector against vectorization factor.
(vect_analyze_loop): Determine vectorizaion factor before
analyzing data dependences.
* tree-vectorizer.c (loops_num): Make it externally visible and
rename ...
* tree-vectorizer.c (vect_loops_num): ... new name.
* tree-vectorizer.h (vect_loops_num): New.
* tree-vect-analyze.c (vect_analyze_operations): Check
vectorizable codition.
* tree-vect-transform.c (vect_is_simple_cond): New function.
(vectorizable_condition): New function.
(vect_transform_stmt): Handle condition_vec_info_type.
* tree-vectorizer.h (enum stmt_vec_info_type): Add
condition_vec_info_type.
(vectorizable_condition): New.
* lib/target-supports.exp (check_effective_target_vect_condition): New.
* gcc.dg/vect/vect-ifcvt-1.c: New test.
* gcc.dg/vect/vect-ifcvt-2.c: New test.
* gcc.dg/vect/vect-ifcvt-3.c: New test.
* gcc.dg/vect/vect-ifcvt-4.c: New test.
* gcc.dg/vect/vect-ifcvt-5.c: New test.
* gcc.dg/vect/vect-ifcvt-6.c: New test.
* gcc.dg/vect/vect-ifcvt-7.c: New test.
* gcc.dg/vect/vect-none.c: Now one loop is vectorized.
* gcc.dg/vect/vect-dv-1.c: New test.
* gcc.dg/vect/vect-dv-2.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@97999 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-vect-transform.c')
-rw-r--r-- | gcc/tree-vect-transform.c | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/gcc/tree-vect-transform.c b/gcc/tree-vect-transform.c index 47792284334..69d532f894f 100644 --- a/gcc/tree-vect-transform.c +++ b/gcc/tree-vect-transform.c @@ -57,6 +57,7 @@ static tree vect_get_vec_def_for_operand (tree, tree); static tree vect_init_vector (tree, tree); static void vect_finish_stmt_generation (tree stmt, tree vec_stmt, block_stmt_iterator *bsi); +static bool vect_is_simple_cond (tree, loop_vec_info); static void update_vuses_to_preheader (tree, struct loop*); /* Utility function dealing with loop peeling (not peeling itself). */ @@ -1141,6 +1142,145 @@ vectorizable_load (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt) return true; } +/* Function vect_is_simple_cond. + + Input: + LOOP - the loop that is being vectorized. + COND - Condition that is checked for simple use. + + Returns whether a COND can be vectorized. Checkes whether + condition operands are supportable using vec_is_simple_use. */ + +static bool +vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo) +{ + tree lhs, rhs; + + if (TREE_CODE_CLASS (TREE_CODE (cond)) != tcc_comparison) + return false; + + lhs = TREE_OPERAND (cond, 0); + rhs = TREE_OPERAND (cond, 1); + + if (TREE_CODE (lhs) == SSA_NAME) + { + tree lhs_def_stmt = SSA_NAME_DEF_STMT (lhs); + if (!vect_is_simple_use (lhs, loop_vinfo, &lhs_def_stmt)) + return false; + } + else if (TREE_CODE (lhs) != INTEGER_CST && TREE_CODE (lhs) != REAL_CST) + return false; + + if (TREE_CODE (rhs) == SSA_NAME) + { + tree rhs_def_stmt = SSA_NAME_DEF_STMT (rhs); + if (!vect_is_simple_use (rhs, loop_vinfo, &rhs_def_stmt)) + return false; + } + else if (TREE_CODE (rhs) != INTEGER_CST && TREE_CODE (rhs) != REAL_CST) + return false; + + return true; +} + +/* vectorizable_condition. + + Check if STMT is conditional modify expression that can be vectorized. + If VEC_STMT is also passed, vectorize the STMT: create a vectorized + stmt using VEC_COND_EXPR to replace it, put it in VEC_STMT, and insert it + at BSI. + + Return FALSE if not a vectorizable STMT, TRUE otherwise. */ + +bool +vectorizable_condition (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt) +{ + tree scalar_dest = NULL_TREE; + tree vec_dest = NULL_TREE; + tree op = NULL_TREE; + tree cond_expr, then_clause, else_clause; + stmt_vec_info stmt_info = vinfo_for_stmt (stmt); + tree vectype = STMT_VINFO_VECTYPE (stmt_info); + tree vec_cond_lhs, vec_cond_rhs, vec_then_clause, vec_else_clause; + tree vec_compare, vec_cond_expr; + tree new_temp; + loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info); + enum machine_mode vec_mode; + + if (!STMT_VINFO_RELEVANT_P (stmt_info)) + return false; + + if (TREE_CODE (stmt) != MODIFY_EXPR) + return false; + + op = TREE_OPERAND (stmt, 1); + + if (TREE_CODE (op) != COND_EXPR) + return false; + + cond_expr = TREE_OPERAND (op, 0); + then_clause = TREE_OPERAND (op, 1); + else_clause = TREE_OPERAND (op, 2); + + if (!vect_is_simple_cond (cond_expr, loop_vinfo)) + return false; + + if (TREE_CODE (then_clause) == SSA_NAME) + { + tree then_def_stmt = SSA_NAME_DEF_STMT (then_clause); + if (!vect_is_simple_use (then_clause, loop_vinfo, &then_def_stmt)) + return false; + } + else if (TREE_CODE (then_clause) != INTEGER_CST + && TREE_CODE (then_clause) != REAL_CST) + return false; + + if (TREE_CODE (else_clause) == SSA_NAME) + { + tree else_def_stmt = SSA_NAME_DEF_STMT (else_clause); + if (!vect_is_simple_use (else_clause, loop_vinfo, &else_def_stmt)) + return false; + } + else if (TREE_CODE (else_clause) != INTEGER_CST + && TREE_CODE (else_clause) != REAL_CST) + return false; + + + vec_mode = TYPE_MODE (vectype); + + if (!vec_stmt) + { + STMT_VINFO_TYPE (stmt_info) = condition_vec_info_type; + return expand_vec_cond_expr_p (op, vec_mode); + } + + /* Transform */ + + /* Handle def. */ + scalar_dest = TREE_OPERAND (stmt, 0); + vec_dest = vect_create_destination_var (scalar_dest, vectype); + + /* Handle cond expr. */ + vec_cond_lhs = + vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 0), stmt); + vec_cond_rhs = + vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1), stmt); + vec_then_clause = vect_get_vec_def_for_operand (then_clause, stmt); + vec_else_clause = vect_get_vec_def_for_operand (else_clause, stmt); + + /* Arguments are ready. create the new vector stmt. */ + vec_compare = build2 (TREE_CODE (cond_expr), vectype, + vec_cond_lhs, vec_cond_rhs); + vec_cond_expr = build (VEC_COND_EXPR, vectype, + vec_compare, vec_then_clause, vec_else_clause); + + *vec_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, vec_cond_expr); + new_temp = make_ssa_name (vec_dest, *vec_stmt); + TREE_OPERAND (*vec_stmt, 0) = new_temp; + vect_finish_stmt_generation (stmt, *vec_stmt, bsi); + + return true; +} /* Function vect_transform_stmt. @@ -1176,6 +1316,12 @@ vect_transform_stmt (tree stmt, block_stmt_iterator *bsi) gcc_assert (done); is_store = true; break; + + case condition_vec_info_type: + done = vectorizable_condition (stmt, bsi, &vec_stmt); + gcc_assert (done); + break; + default: if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC)) fprintf (vect_dump, "stmt not supported."); |