summaryrefslogtreecommitdiff
path: root/gcc/tree-complex.c
diff options
context:
space:
mode:
authorPaolo Bonzini <bonzini@gcc.gnu.org>2005-04-27 09:12:05 +0000
committerPaolo Bonzini <bonzini@gcc.gnu.org>2005-04-27 09:12:05 +0000
commitc4336539b95d8ec3ff5b25d72eee0c4f47c4edd7 (patch)
treee30fc63fb8514b4f3b004d75368766b03aee6866 /gcc/tree-complex.c
parente820471b5803045c21828abf910953991771ce50 (diff)
downloadgcc-c4336539b95d8ec3ff5b25d72eee0c4f47c4edd7.tar.gz
tree-complex.c (expand_vector_operation): New, extracted from expand_vector_operations_1.
gcc: 2004-04-27 Paolo Bonzini <bonzini@gnu.org> * tree-complex.c (expand_vector_operation): New, extracted from expand_vector_operations_1. (tree_vec_extract): Build a NOP_EXPR. (expand_vec_parallel): Do not care about returning the correct type. (expand_vector_operations_1): Call expand_vector_operation. Build the VIEW_CONVERT_EXPR on the left side of MODIFY_EXPRs. * tree-complex.c (gate_expand_vector_operations): New. (pass_lower_vector_ssa): Use it. * tree-optimize.c (init_tree_optimization_passes): Include pass_lower_vector_ssa. * tree-vect-transform.c (vect_min_worthwhile_factor): New. (vectorizable_operation): Use it. * tree-vectorizer.c (get_vectype_for_scalar_type): Accept integer modes for the vector type. * defaults.h (UNITS_PER_SIMD_WORD): Default to UNITS_PER_WORD. * tree-vect-analyze.c (vect_enhance_data_refs_alignment): Do not cope with UNITS_PER_SIMD_WORD == 0. * tree-vectorizer.c (get_vectype_for_scalar_type): Check if the scalar type is not bigger than UNITS_PER_SIMD_WORD. (vectorize_loops): Do not check that UNITS_PER_SIMD_WORD > 0. * config/i386/i386.h (UNITS_PER_SIMD_WORD): Default to UNITS_PER_WORD. * config/mips/mips.h (UNITS_PER_SIMD_WORD): Likewise. * config/rs6000/rs6000.h (UNITS_PER_SIMD_WORD): Likewise. * config/sparc/sparc.h (UNITS_PER_SIMD_WORD): Likewise. * config/alpha/alpha.h (UNITS_PER_SIMD_WORD): Remove. * config/bfin/bfin.h (UNITS_PER_SIMD_WORD): Remove. * config/ia64/ia64.h (UNITS_PER_SIMD_WORD): Remove. * doc/tm.texi (UNITS_PER_WORD): Rephrase more accurately. (UNITS_PER_SIMD_WORD): New. gcc/testsuite: 2004-04-27 Paolo Bonzini <bonzini@gnu.org> * gcc.dg/tree-ssa/gen-vect-11.c, gcc.dg/tree-ssa/gen-vect-11a.c, gcc.dg/tree-ssa/gen-vect-11b.c, gcc.dg/tree-ssa/gen-vect-11c.c, gcc.dg/tree-ssa/gen-vect-2.c, gcc.dg/tree-ssa/gen-vect-25.c, gcc.dg/tree-ssa/gen-vect-26.c, gcc.dg/tree-ssa/gen-vect-28.c, gcc.dg/tree-ssa/gen-vect-32.c: New. * gcc.dg/vect/vect-82.c, gcc.dg/vect/vect-83.c: Fix dg-final. * gcc.dg/vect/vect-82_64.c, gcc.dg/vect/vect-83_64.c: Remove xfail, don't run on PPC32. CVS: Enter Log. Lines beginning with `CVS:' are removed automatically CVS: CVS: Committing in . CVS: CVS: Modified Files: CVS: tree-complex.c tree-optimize.c tree-vect-analyze.c defaults.h CVS: tree-vect-transform.c tree-vectorizer.c ChangeLog CVS: testsuite/ChangeLog config/alpha/alpha.h config/bfin/bfin.h CVS: config/i386/i386.h config/ia64/ia64.h config/mips/mips.h CVS: config/rs6000/rs6000.h CVS: config/sparc/sparc.h doc/tm.texi CVS: testsuite/gcc.dg/vect/vect-82.c CVS: testsuite/gcc.dg/vect/vect-82_64.c CVS: testsuite/gcc.dg/vect/vect-83.c CVS: testsuite/gcc.dg/vect/vect-83_64.c CVS: Added Files: CVS: testsuite/gcc.dg/tree-ssa/gen-vect-11.c CVS: testsuite/gcc.dg/tree-ssa/gen-vect-11a.c CVS: testsuite/gcc.dg/tree-ssa/gen-vect-11b.c CVS: testsuite/gcc.dg/tree-ssa/gen-vect-11c.c CVS: testsuite/gcc.dg/tree-ssa/gen-vect-2.c CVS: testsuite/gcc.dg/tree-ssa/gen-vect-25.c CVS: testsuite/gcc.dg/tree-ssa/gen-vect-26.c CVS: testsuite/gcc.dg/tree-ssa/gen-vect-28.c CVS: testsuite/gcc.dg/tree-ssa/gen-vect-32.c CVS: ---------------------------------------------------------------------- From-SVN: r98818
Diffstat (limited to 'gcc/tree-complex.c')
-rw-r--r--gcc/tree-complex.c157
1 files changed, 90 insertions, 67 deletions
diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c
index 18582c1b20b..98b6c561503 100644
--- a/gcc/tree-complex.c
+++ b/gcc/tree-complex.c
@@ -632,8 +632,13 @@ tree_vec_extract (block_stmt_iterator *bsi, tree type,
{
if (bitpos)
return gimplify_build3 (bsi, BIT_FIELD_REF, type, t, bitsize, bitpos);
- else
+
+ /* Build a conversion; VIEW_CONVERT_EXPR is very expensive unless T will
+ anyway be stored in memory, so prefer NOP_EXPR. */
+ else if (TYPE_MODE (type) == BLKmode)
return gimplify_build1 (bsi, VIEW_CONVERT_EXPR, type, t);
+ else
+ return gimplify_build1 (bsi, NOP_EXPR, type, t);
}
static tree
@@ -783,7 +788,7 @@ expand_vector_parallel (block_stmt_iterator *bsi, elem_op_func f, tree type,
result = f (bsi, compute_type, a, b, NULL_TREE, NULL_TREE, code);
}
- return build1 (VIEW_CONVERT_EXPR, type, result);
+ return result;
}
/* Expand a vector operation to scalars; for integer types we can use
@@ -810,6 +815,60 @@ expand_vector_addition (block_stmt_iterator *bsi,
a, b, code);
}
+static tree
+expand_vector_operation (block_stmt_iterator *bsi, tree type, tree compute_type,
+ tree rhs, enum tree_code code)
+{
+ enum machine_mode compute_mode = TYPE_MODE (compute_type);
+
+ /* If the compute mode is not a vector mode (hence we are not decomposing
+ a BLKmode vector to smaller, hardware-supported vectors), we may want
+ to expand the operations in parallel. */
+ if (GET_MODE_CLASS (compute_mode) != MODE_VECTOR_INT
+ && GET_MODE_CLASS (compute_mode) != MODE_VECTOR_FLOAT)
+ switch (code)
+ {
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ if (!TYPE_TRAP_SIGNED (type))
+ return expand_vector_addition (bsi, do_binop, do_plus_minus, type,
+ TREE_OPERAND (rhs, 0),
+ TREE_OPERAND (rhs, 1), code);
+ break;
+
+ case NEGATE_EXPR:
+ if (!TYPE_TRAP_SIGNED (type))
+ return expand_vector_addition (bsi, do_unop, do_negate, type,
+ TREE_OPERAND (rhs, 0),
+ NULL_TREE, code);
+ break;
+
+ case BIT_AND_EXPR:
+ case BIT_IOR_EXPR:
+ case BIT_XOR_EXPR:
+ return expand_vector_parallel (bsi, do_binop, type,
+ TREE_OPERAND (rhs, 0),
+ TREE_OPERAND (rhs, 1), code);
+
+ case BIT_NOT_EXPR:
+ return expand_vector_parallel (bsi, do_unop, type,
+ TREE_OPERAND (rhs, 0),
+ NULL_TREE, code);
+
+ default:
+ break;
+ }
+
+ if (TREE_CODE_CLASS (code) == tcc_unary)
+ return expand_vector_piecewise (bsi, do_unop, type, compute_type,
+ TREE_OPERAND (rhs, 0),
+ NULL_TREE, code);
+ else
+ return expand_vector_piecewise (bsi, do_binop, type, compute_type,
+ TREE_OPERAND (rhs, 0),
+ TREE_OPERAND (rhs, 1), code);
+}
+
/* Return a type for the widest vector mode whose components are of mode
INNER_MODE, or NULL_TREE if none is found. */
static tree
@@ -841,7 +900,7 @@ static void
expand_vector_operations_1 (block_stmt_iterator *bsi)
{
tree stmt = bsi_stmt (*bsi);
- tree *p_rhs, rhs, type, compute_type;
+ tree *p_lhs, *p_rhs, lhs, rhs, type, compute_type;
enum tree_code code;
enum machine_mode compute_mode;
optab op;
@@ -856,7 +915,9 @@ expand_vector_operations_1 (block_stmt_iterator *bsi)
/* FALLTHRU */
case MODIFY_EXPR:
+ p_lhs = &TREE_OPERAND (stmt, 0);
p_rhs = &TREE_OPERAND (stmt, 1);
+ lhs = *p_lhs;
rhs = *p_rhs;
break;
@@ -897,86 +958,48 @@ expand_vector_operations_1 (block_stmt_iterator *bsi)
compute_type = vector_compute_type;
}
- compute_mode = TYPE_MODE (compute_type);
-
/* If we are breaking a BLKmode vector into smaller pieces,
type_for_widest_vector_mode has already looked into the optab,
so skip these checks. */
if (compute_type == type)
{
+ compute_mode = TYPE_MODE (compute_type);
if ((GET_MODE_CLASS (compute_mode) == MODE_VECTOR_INT
|| GET_MODE_CLASS (compute_mode) == MODE_VECTOR_FLOAT)
&& op != NULL
&& op->handlers[compute_mode].insn_code != CODE_FOR_nothing)
return;
else
- {
- /* There is no operation in hardware, so fall back to scalars. */
- compute_type = TREE_TYPE (type);
- compute_mode = TYPE_MODE (compute_type);
- }
+ /* There is no operation in hardware, so fall back to scalars. */
+ compute_type = TREE_TYPE (type);
}
- /* If the compute mode is not a vector mode (hence we are decomposing
- a BLKmode vector to smaller, hardware-supported vectors), we may
- want to expand the operations in parallel. */
- if (GET_MODE_CLASS (compute_mode) != MODE_VECTOR_INT
- && GET_MODE_CLASS (compute_mode) != MODE_VECTOR_FLOAT)
- switch (code)
- {
- case PLUS_EXPR:
- case MINUS_EXPR:
- if (TYPE_TRAP_SIGNED (type))
- break;
-
- *p_rhs = expand_vector_addition (bsi, do_binop, do_plus_minus, type,
- TREE_OPERAND (rhs, 0),
- TREE_OPERAND (rhs, 1), code);
- mark_stmt_modified (bsi_stmt (*bsi));
- return;
-
- case NEGATE_EXPR:
- if (TYPE_TRAP_SIGNED (type))
- break;
-
- *p_rhs = expand_vector_addition (bsi, do_unop, do_negate, type,
- TREE_OPERAND (rhs, 0),
- NULL_TREE, code);
- mark_stmt_modified (bsi_stmt (*bsi));
- return;
-
- case BIT_AND_EXPR:
- case BIT_IOR_EXPR:
- case BIT_XOR_EXPR:
- *p_rhs = expand_vector_parallel (bsi, do_binop, type,
- TREE_OPERAND (rhs, 0),
- TREE_OPERAND (rhs, 1), code);
- mark_stmt_modified (bsi_stmt (*bsi));
- return;
-
- case BIT_NOT_EXPR:
- *p_rhs = expand_vector_parallel (bsi, do_unop, type,
- TREE_OPERAND (rhs, 0),
- NULL_TREE, code);
- mark_stmt_modified (bsi_stmt (*bsi));
- return;
-
- default:
- break;
- }
-
- if (TREE_CODE_CLASS (code) == tcc_unary)
- *p_rhs = expand_vector_piecewise (bsi, do_unop, type, compute_type,
- TREE_OPERAND (rhs, 0),
- NULL_TREE, code);
+ rhs = expand_vector_operation (bsi, type, compute_type, rhs, code);
+ if (lang_hooks.types_compatible_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
+ *p_rhs = rhs;
else
- *p_rhs = expand_vector_piecewise (bsi, do_binop, type, compute_type,
- TREE_OPERAND (rhs, 0),
- TREE_OPERAND (rhs, 1), code);
+ {
+ /* Build a conversion; VIEW_CONVERT_EXPR is very expensive unless T will
+ be stored in memory anyway, so prefer NOP_EXPR. Also, perform the
+ VIEW_CONVERT_EXPR on the left side of the assignment. */
+ if (TYPE_MODE (TREE_TYPE (rhs)) == BLKmode)
+ *p_lhs = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (rhs), lhs);
+ else
+ *p_rhs = gimplify_build1 (bsi, NOP_EXPR, TREE_TYPE (lhs), rhs);
+ }
mark_stmt_modified (bsi_stmt (*bsi));
}
+/* Use this to lower vector operations introduced by the vectorizer,
+ if it may need the bit-twiddling tricks implemented in this file. */
+
+static bool
+gate_expand_vector_operations (void)
+{
+ return flag_tree_vectorize != 0;
+}
+
static void
expand_vector_operations (void)
{
@@ -1015,8 +1038,8 @@ tree_lower_operations (void)
struct tree_opt_pass pass_lower_vector_ssa =
{
- "vector", /* name */
- NULL, /* gate */
+ "veclower", /* name */
+ gate_expand_vector_operations, /* gate */
expand_vector_operations, /* execute */
NULL, /* sub */
NULL, /* next */