diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-11-21 14:29:53 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-11-21 14:29:53 +0000 |
commit | c37bea1361b837bfa6083070c1f48916acb2fe73 (patch) | |
tree | 780e63d411978fb8d8cb93106c7cfed5aedf45ff /gcc/tree-vect-patterns.c | |
parent | cd36b2c0e14e6a32b9ed41d460d1c330f2775894 (diff) | |
download | gcc-c37bea1361b837bfa6083070c1f48916acb2fe73.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@119056 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-vect-patterns.c')
-rw-r--r-- | gcc/tree-vect-patterns.c | 91 |
1 files changed, 90 insertions, 1 deletions
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: |