This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[autovect] generic extract_even/odd
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 1 Dec 2005 13:27:44 -0800
- Subject: [autovect] generic extract_even/odd
Some common code that I expect will be used by several targets.
If a target has both interleave_high and interleave_low, then
sorting elements into even and odd sets can be done with three
operations.
r~
* targhooks.c (interleave_vectorize_builtin_extract_evenodd): New.
(interleave_vectorize_builtin_extract_even): New.
(interleave_vectorize_builtin_extract_odd): New.
* targhooks.h: Declare them.
* config/i386/i386.c (TARGET_VECTORIZE_BUILTIN_EXTRACT_EVEN): New.
(TARGET_VECTORIZE_BUILTIN_EXTRACT_ODD): New.
=== gcc/config/i386/i386.c
==================================================================
--- gcc/config/i386/i386.c (revision 107839)
+++ gcc/config/i386/i386.c (local)
@@ -1087,6 +1087,12 @@
#undef TARGET_VECTOR_MODE_SUPPORTED_P
#define TARGET_VECTOR_MODE_SUPPORTED_P ix86_vector_mode_supported_p
+#undef TARGET_VECTORIZE_BUILTIN_EXTRACT_EVEN
+#define TARGET_VECTORIZE_BUILTIN_EXTRACT_EVEN \
+ interleave_vectorize_builtin_extract_even
+#undef TARGET_VECTORIZE_BUILTIN_EXTRACT_ODD
+#define TARGET_VECTORIZE_BUILTIN_EXTRACT_ODD \
+ interleave_vectorize_builtin_extract_odd
#ifdef HAVE_AS_TLS
#undef TARGET_ASM_OUTPUT_DWARF_DTPREL
=== gcc/targhooks.c
==================================================================
--- gcc/targhooks.c (revision 107839)
+++ gcc/targhooks.c (local)
@@ -58,6 +58,8 @@
#include "output.h"
#include "toplev.h"
#include "function.h"
+#include "tree-flow.h"
+#include "optabs.h"
#include "target.h"
#include "tm_p.h"
#include "target-def.h"
@@ -439,4 +441,65 @@
#endif
}
+static tree
+interleave_vectorize_builtin_extract_evenodd (tree dest, tree vec1,
+ tree vec2, tree stmt, bool odd_p)
+{
+ tree type;
+ enum machine_mode mode;
+ block_stmt_iterator bsi;
+ tree th, tl, result, x;
+
+ type = TREE_TYPE (dest);
+ mode = TYPE_MODE (type);
+
+ /* We require both high and low interleaves for the mode. */
+ if (vec_interleave_high_optab->handlers[mode].insn_code == CODE_FOR_nothing
+ || vec_interleave_low_optab->handlers[mode].insn_code == CODE_FOR_nothing)
+ return NULL;
+
+ bsi = bsi_for_stmt (stmt);
+
+ th = make_rename_temp (type, NULL);
+ x = build2 (VEC_INTERLEAVE_HIGH_EXPR, type, vec1, vec2);
+ x = build2 (MODIFY_EXPR, type, th, x);
+ th = make_ssa_name (th, x);
+ TREE_OPERAND (x, 0) = th;
+ bsi_insert_before (&bsi, x, BSI_SAME_STMT);
+
+ tl = make_rename_temp (type, NULL);
+ x = build2 (VEC_INTERLEAVE_LOW_EXPR, type, vec1, vec2);
+ x = build2 (MODIFY_EXPR, type, tl, x);
+ tl = make_ssa_name (tl, x);
+ TREE_OPERAND (x, 0) = tl;
+ bsi_insert_before (&bsi, x, BSI_SAME_STMT);
+
+ result = make_rename_temp (type, NULL);
+ /* ??? Endianness issues? */
+ x = build2 (odd_p ? VEC_INTERLEAVE_HIGH_EXPR : VEC_INTERLEAVE_LOW_EXPR,
+ type, th, tl);
+ x = build2 (MODIFY_EXPR, type, result, x);
+ result = make_ssa_name (result, x);
+ TREE_OPERAND (x, 0) = result;
+ bsi_insert_before (&bsi, x, BSI_SAME_STMT);
+
+ return result;
+}
+
+tree
+interleave_vectorize_builtin_extract_even (tree dest, tree vec1,
+ tree vec2, tree stmt)
+{
+ return interleave_vectorize_builtin_extract_evenodd (dest, vec1, vec2,
+ stmt, false);
+}
+
+tree
+interleave_vectorize_builtin_extract_odd (tree dest, tree vec1,
+ tree vec2, tree stmt)
+{
+ return interleave_vectorize_builtin_extract_evenodd (dest, vec1, vec2,
+ stmt, true);
+}
+
#include "gt-targhooks.h"
=== gcc/targhooks.h
==================================================================
--- gcc/targhooks.h (revision 107839)
+++ gcc/targhooks.h (local)
@@ -69,3 +69,5 @@
extern bool hook_bool_rtx_commutative_p (rtx, int);
extern rtx default_function_value (tree, tree, bool);
+extern tree interleave_vectorize_builtin_extract_even (tree, tree, tree, tree);
+extern tree interleave_vectorize_builtin_extract_odd (tree, tree, tree, tree);