diff options
Diffstat (limited to 'gcc/tree-vect-patterns.c')
-rw-r--r-- | gcc/tree-vect-patterns.c | 67 |
1 files changed, 62 insertions, 5 deletions
diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index 9ac11b0..67ab90f 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -334,12 +334,69 @@ vect_recog_dot_prod_pattern (tree last_stmt, tree *type_in, tree *type_out) */ static tree -vect_recog_widen_mult_pattern (tree last_stmt ATTRIBUTE_UNUSED, - tree *type_in ATTRIBUTE_UNUSED, - tree *type_out ATTRIBUTE_UNUSED) +vect_recog_widen_mult_pattern (tree last_stmt, + tree *type_in, + tree *type_out) { - /* Yet to be implemented. */ - return NULL; + tree expr; + tree def_stmt0, def_stmt1; + tree oprnd0, oprnd1; + tree type, half_type0, half_type1; + tree pattern_expr; + tree vectype; + tree dummy; + enum tree_code dummy_code; + + if (TREE_CODE (last_stmt) != MODIFY_EXPR) + return NULL; + + expr = TREE_OPERAND (last_stmt, 1); + type = TREE_TYPE (expr); + + /* Starting from LAST_STMT, follow the defs of its uses in search + of the above pattern. */ + + if (TREE_CODE (expr) != MULT_EXPR) + return NULL; + + oprnd0 = TREE_OPERAND (expr, 0); + oprnd1 = TREE_OPERAND (expr, 1); + if (TYPE_MAIN_VARIANT (TREE_TYPE (oprnd0)) != TYPE_MAIN_VARIANT (type) + || TYPE_MAIN_VARIANT (TREE_TYPE (oprnd1)) != TYPE_MAIN_VARIANT (type)) + return NULL; + + /* Check argument 0 */ + if (!widened_name_p (oprnd0, last_stmt, &half_type0, &def_stmt0)) + return NULL; + oprnd0 = TREE_OPERAND (TREE_OPERAND (def_stmt0, 1), 0); + + /* Check argument 1 */ + if (!widened_name_p (oprnd1, last_stmt, &half_type1, &def_stmt1)) + return NULL; + oprnd1 = TREE_OPERAND (TREE_OPERAND (def_stmt1, 1), 0); + + if (TYPE_MAIN_VARIANT (half_type0) != TYPE_MAIN_VARIANT (half_type1)) + return NULL; + + /* Pattern detected. */ + if (vect_print_dump_info (REPORT_DETAILS)) + fprintf (vect_dump, "vect_recog_widen_mult_pattern: detected: "); + + /* Check target support */ + vectype = get_vectype_for_scalar_type (half_type0); + if (!supportable_widening_operation (WIDEN_MULT_EXPR, last_stmt, vectype, + &dummy, &dummy, &dummy_code, + &dummy_code)) + return NULL; + + *type_in = vectype; + *type_out = NULL_TREE; + + /* Pattern supported. Create a stmt to be used to replace the pattern: */ + pattern_expr = build2 (WIDEN_MULT_EXPR, type, oprnd0, oprnd1); + if (vect_print_dump_info (REPORT_DETAILS)) + print_generic_expr (vect_dump, pattern_expr, TDF_SLIM); + return pattern_expr; } |