diff options
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/vect-pow-1.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/vect-pow-2.c | 14 | ||||
-rw-r--r-- | gcc/tree-vect-patterns.c | 91 | ||||
-rw-r--r-- | gcc/tree-vectorizer.h | 2 |
6 files changed, 131 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 99b91c0a9b9..fb4844ada07 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 d0f9bc073fe..b6d5d4a11a1 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 00000000000..2c29cbaf6de --- /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 00000000000..dc3e7c0a486 --- /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 67ab90f1eec..3e40fc79b5a 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 55e13776266..8341ad00a07 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); |