diff options
author | Paolo Bonzini <bonzini@gcc.gnu.org> | 2005-04-27 09:12:05 +0000 |
---|---|---|
committer | Paolo Bonzini <bonzini@gcc.gnu.org> | 2005-04-27 09:12:05 +0000 |
commit | c4336539b95d8ec3ff5b25d72eee0c4f47c4edd7 (patch) | |
tree | e30fc63fb8514b4f3b004d75368766b03aee6866 /gcc/tree-complex.c | |
parent | e820471b5803045c21828abf910953991771ce50 (diff) | |
download | gcc-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.c | 157 |
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 */ |