aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2006-11-21 14:29:53 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2006-11-21 14:29:53 +0000
commit0b2229b0b06b8799aaf9a982c66a1175d3ea8a28 (patch)
tree780e63d411978fb8d8cb93106c7cfed5aedf45ff
parent84e32cbb1fa266ee63c76b35436728bc5d689153 (diff)
downloadgcc-0b2229b0b06b8799aaf9a982c66a1175d3ea8a28.zip
gcc-0b2229b0b06b8799aaf9a982c66a1175d3ea8a28.tar.gz
gcc-0b2229b0b06b8799aaf9a982c66a1175d3ea8a28.tar.bz2
tree-vectorizer.h (NUM_PATTERNS): Increase.
2006-11-21 Richard Guenther <rguenther@suse.de> * tree-vectorizer.h (NUM_PATTERNS): Increase. * tree-vect-patterns.c (vect_vect_recog_func_ptrs): Add vect_recog_pow_pattern. (vect_recog_pow_pattern): New function. * gcc.dg/vect/vect-pow-1.c: New testcase. * gcc.dg/vect/vect-pow-2.c: Likewise. From-SVN: r119056
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-pow-1.c14
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-pow-2.c14
-rw-r--r--gcc/tree-vect-patterns.c91
-rw-r--r--gcc/tree-vectorizer.h2
6 files changed, 131 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 99b91c0..fb4844a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2006-11-21 Richard Guenther <rguenther@suse.de>
+
+ * tree-vectorizer.h (NUM_PATTERNS): Increase.
+ * tree-vect-patterns.c (vect_vect_recog_func_ptrs): Add
+ vect_recog_pow_pattern.
+ (vect_recog_pow_pattern): New function.
+
2006-11-21 Bernd Schmidt <bernd.schmidt@analog.com>
* config/bfin/bfin.opt (mstack-check-l1): New.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d0f9bc0..b6d5d4a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2006-11-21 Richard Guenther <rguenther@suse.de>
+
+ * gcc.dg/vect/vect-pow-1.c: New testcase.
+ * gcc.dg/vect/vect-pow-2.c: Likewise.
+
2006-11-21 Jakub Jelinek <jakub@redhat.com>
PR c++/29570
diff --git a/gcc/testsuite/gcc.dg/vect/vect-pow-1.c b/gcc/testsuite/gcc.dg/vect/vect-pow-1.c
new file mode 100644
index 0000000..2c29cba
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-pow-1.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math -fdump-tree-vect-details" } */
+
+double x[256];
+
+void foo(void)
+{
+ int i;
+ for (i=0; i<256; ++i)
+ x[i] = x[i] * x[i];
+}
+
+/* { dg-final { scan-tree-dump "pattern recognized" "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-pow-2.c b/gcc/testsuite/gcc.dg/vect/vect-pow-2.c
new file mode 100644
index 0000000..dc3e7c0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-pow-2.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -fno-math-errno -fdump-tree-vect-details" } */
+
+double x[256];
+
+void foo(void)
+{
+ int i;
+ for (i=0; i<256; ++i)
+ x[i] = __builtin_pow (x[i], 0.5);
+}
+
+/* { dg-final { scan-tree-dump "pattern recognized" "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c
index 67ab90f..3e40fc7 100644
--- a/gcc/tree-vect-patterns.c
+++ b/gcc/tree-vect-patterns.c
@@ -50,10 +50,12 @@ static bool widened_name_p (tree, tree, tree *, tree *);
static tree vect_recog_widen_sum_pattern (tree, tree *, tree *);
static tree vect_recog_widen_mult_pattern (tree, tree *, tree *);
static tree vect_recog_dot_prod_pattern (tree, tree *, tree *);
+static tree vect_recog_pow_pattern (tree, tree *, tree *);
static vect_recog_func_ptr vect_vect_recog_func_ptrs[NUM_PATTERNS] = {
vect_recog_widen_mult_pattern,
vect_recog_widen_sum_pattern,
- vect_recog_dot_prod_pattern};
+ vect_recog_dot_prod_pattern,
+ vect_recog_pow_pattern};
/* Function widened_name_p
@@ -400,6 +402,93 @@ vect_recog_widen_mult_pattern (tree last_stmt,
}
+/* Function vect_recog_pow_pattern
+
+ Try to find the following pattern:
+
+ x = POW (y, N);
+
+ with POW being one of pow, powf, powi, powif and N being
+ either 2 or 0.5.
+
+ Input:
+
+ * LAST_STMT: A stmt from which the pattern search begins.
+
+ Output:
+
+ * TYPE_IN: The type of the input arguments to the pattern.
+
+ * TYPE_OUT: The type of the output of this pattern.
+
+ * Return value: A new stmt that will be used to replace the sequence of
+ stmts that constitute the pattern. In this case it will be:
+ x * x
+ or
+ sqrt (x)
+*/
+
+static tree
+vect_recog_pow_pattern (tree last_stmt, tree *type_in, tree *type_out)
+{
+ tree expr;
+ tree type;
+ tree fn, arglist, base, exp;
+
+ if (TREE_CODE (last_stmt) != MODIFY_EXPR)
+ return NULL;
+
+ expr = TREE_OPERAND (last_stmt, 1);
+ type = TREE_TYPE (expr);
+
+ if (TREE_CODE (expr) != CALL_EXPR)
+ return NULL_TREE;
+
+ fn = get_callee_fndecl (expr);
+ arglist = TREE_OPERAND (expr, 1);
+ switch (DECL_FUNCTION_CODE (fn))
+ {
+ case BUILT_IN_POWIF:
+ case BUILT_IN_POWI:
+ case BUILT_IN_POWF:
+ case BUILT_IN_POW:
+ base = TREE_VALUE (arglist);
+ exp = TREE_VALUE (TREE_CHAIN (arglist));
+ if (TREE_CODE (exp) != REAL_CST
+ && TREE_CODE (exp) != INTEGER_CST)
+ return NULL_TREE;
+ break;
+
+ default:;
+ return NULL_TREE;
+ }
+
+ /* We now have a pow or powi builtin function call with a constant
+ exponent. */
+
+ *type_in = get_vectype_for_scalar_type (TREE_TYPE (base));
+ *type_out = NULL_TREE;
+
+ /* Catch squaring. */
+ if ((host_integerp (exp, 0)
+ && tree_low_cst (exp, 0) == 2)
+ || (TREE_CODE (exp) == REAL_CST
+ && REAL_VALUES_EQUAL (TREE_REAL_CST (exp), dconst2)))
+ return build2 (MULT_EXPR, TREE_TYPE (base), base, base);
+
+ /* Catch square root. */
+ if (TREE_CODE (exp) == REAL_CST
+ && REAL_VALUES_EQUAL (TREE_REAL_CST (exp), dconsthalf))
+ {
+ tree newfn = mathfn_built_in (TREE_TYPE (base), BUILT_IN_SQRT);
+ tree newarglist = build_tree_list (NULL_TREE, base);
+ return build_function_call_expr (newfn, newarglist);
+ }
+
+ return NULL_TREE;
+}
+
+
/* Function vect_recog_widen_sum_pattern
Try to find the following pattern:
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index 55e1377..8341ad0 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -357,7 +357,7 @@ extern loop_vec_info vect_analyze_loop (struct loop *);
Additional pattern recognition functions can (and will) be added
in the future. */
typedef tree (* vect_recog_func_ptr) (tree, tree *, tree *);
-#define NUM_PATTERNS 3
+#define NUM_PATTERNS 4
void vect_pattern_recog (loop_vec_info);