GCC Middle and Back End API Reference
|
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-fold.h"
#include "ssa.h"
#include "expmed.h"
#include "optabs-tree.h"
#include "insn-config.h"
#include "recog.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "tree-eh.h"
#include "gimplify.h"
#include "gimplify-me.h"
#include "cfgloop.h"
#include "tree-vectorizer.h"
#include "dumpfile.h"
#include "builtins.h"
#include "internal-fn.h"
#include "case-cfn-macros.h"
#include "fold-const-call.h"
#include "attribs.h"
#include "cgraph.h"
#include "omp-simd-clone.h"
#include "predict.h"
#include "tree-vector-builder.h"
#include "tree-ssa-loop-ivopts.h"
#include "vec-perm-indices.h"
#include "gimple-range.h"
#include "alias.h"
Data Structures | |
class | vect_unpromoted_value |
struct | vect_recog_func |
Macros | |
#define | INCLUDE_MEMORY |
Typedefs | |
typedef gimple *(* | vect_recog_func_ptr) (vec_info *, stmt_vec_info, tree *) |
Variables | |
static vect_recog_func | vect_vect_recog_func_ptrs [] |
#define INCLUDE_MEMORY |
Analysis Utilities for Loop Vectorization. Copyright (C) 2006-2024 Free Software Foundation, Inc. Contributed by Dorit Nuzman <dorit@il.ibm.com> This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>.
typedef gimple *(* vect_recog_func_ptr) (vec_info *, stmt_vec_info, tree *) |
|
static |
Helper function of vect_recog_bool_pattern. Do the actual transformations. VAR is an SSA_NAME that should be transformed from bool to a wider integer type, OUT_TYPE is the desired final integer type of the whole pattern. STMT_INFO is the info of the pattern root and is where pattern stmts should be associated with. DEFS is a map of pattern defs.
References absu_hwi(), adjust_bool_pattern_cast(), append_pattern_def_seq(), build2_loc(), build_int_cst(), build_nonstandard_integer_type(), CASE_CONVERT, defs, do_compare(), gcc_assert, gcc_checking_assert, GET_MODE_BITSIZE(), get_vectype_for_scalar_type(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_build_assign(), gimple_location(), gimple_set_location(), NULL, NULL_TREE, SCALAR_TYPE_MODE, SSA_NAME_DEF_STMT, tcc_comparison, TREE_CODE, TREE_CODE_CLASS, TREE_TYPE, TYPE_MODE, TYPE_PRECISION, TYPE_UNSIGNED, useless_type_conversion_p(), and vect_recog_temp_ssa_var().
Referenced by adjust_bool_stmts().
|
static |
Helper function of adjust_bool_pattern. Add a cast to TYPE to a previous stmt (SSA_NAME_DEF_STMT of VAR) adding a cast to STMT_INFOs pattern sequence.
References append_pattern_def_seq(), get_vectype_for_scalar_type(), gimple_assign_lhs(), gimple_build_assign(), NULL, and vect_recog_temp_ssa_var().
Referenced by adjust_bool_pattern().
|
static |
Create pattern stmts for all stmts participating in the bool pattern specified by BOOL_STMT_SET and its root STMT_INFO with the desired type OUT_TYPE. Return the def of the pattern root.
References adjust_bool_pattern(), hash_set< KeyId, Lazy, Traits >::begin(), defs, hash_set< KeyId, Lazy, Traits >::elements(), hash_set< KeyId, Lazy, Traits >::end(), gimple_assign_lhs(), gimple_seq_last_stmt(), i, sort_after_uid(), and STMT_VINFO_PATTERN_DEF_SEQ.
Referenced by vect_recog_bool_pattern().
Add NEW_STMT to VINFO's invariant pattern definition statements. These statements are not vectorized but are materialized as scalar in the loop preheader.
References gimple_seq_add_stmt_without_update(), and vec_info::inv_pattern_def_seq.
Referenced by vect_recog_bool_pattern().
|
inlinestatic |
Add NEW_STMT to STMT_INFO's pattern definition statements. If VECTYPE is nonnull, record that NEW_STMT's vector type is VECTYPE, which might be different from the vector type of the final pattern statement. If VECTYPE is a mask type, SCALAR_TYPE_FOR_MASK is the scalar type from which it was derived.
References vec_info::add_stmt(), gcc_assert, GET_MODE_BITSIZE(), gimple_seq_add_stmt_without_update(), SCALAR_TYPE_MODE, STMT_VINFO_PATTERN_DEF_SEQ, STMT_VINFO_VECTYPE, and VECTOR_BOOLEAN_TYPE_P.
Referenced by adjust_bool_pattern(), adjust_bool_pattern_cast(), apply_binop_and_append_stmt(), build_mask_conversion(), synth_lshift_by_additions(), vect_add_conversion_to_pattern(), vect_convert_input(), vect_convert_output(), vect_recog_average_pattern(), vect_recog_bit_insert_pattern(), vect_recog_bitfield_ref_pattern(), vect_recog_bool_pattern(), vect_recog_build_binary_gimple_stmt(), vect_recog_cond_expr_convert_pattern(), vect_recog_cond_store_pattern(), vect_recog_ctz_ffs_pattern(), vect_recog_divmod_pattern(), vect_recog_gcond_pattern(), vect_recog_mask_conversion_pattern(), vect_recog_mixed_size_cond_pattern(), vect_recog_mod_var_pattern(), vect_recog_popcount_clz_ctz_ffs_pattern(), vect_recog_pow_pattern(), vect_recog_rotate_pattern(), vect_recog_sat_sub_pattern_transform(), vect_recog_vector_vector_shift_pattern(), and vect_synth_mult_by_constant().
|
static |
Helper for vect_synth_mult_by_constant. Apply a binary operation CODE to operands OP1 and OP2, creating a new temporary SSA var in the process if necessary. Append the resulting assignment statements to the sequence in STMT_VINFO. Return the SSA variable that holds the result of the binary operation. If SYNTH_SHIFT_P is true synthesize left shifts using additions.
References append_pattern_def_seq(), gcc_assert, gimple_build_assign(), integer_zerop(), NULL, synth_lshift_by_additions(), TREE_CODE, TREE_INT_CST_LOW, TREE_TYPE, and vect_recog_temp_ssa_var().
Referenced by vect_synth_mult_by_constant().
|
static |
A helper for vect_recog_mask_conversion_pattern. Build conversion of MASK to a type suitable for masking VECTYPE. Built statement gets required vectype and is appended to a pattern sequence of STMT_VINFO. Return converted mask.
References append_pattern_def_seq(), gimple_build_assign(), NULL, TREE_TYPE, truth_type_for(), and vect_recog_temp_ssa_var().
Referenced by vect_convert_mask_for_vectype(), and vect_recog_mask_conversion_pattern().
Helper function of vect_recog_bool_pattern. Called recursively, return true if bool VAR can and should be optimized that way. Assume it shouldn't in case it's a result of a comparison which can be directly vectorized into a vector comparison. Fills in STMTS with all stmts visited during the walk.
References hash_set< KeyId, Lazy, Traits >::add(), build_nonstandard_integer_type(), CASE_CONVERT, cfun, check_bool_pattern(), hash_set< KeyId, Lazy, Traits >::contains(), dyn_cast(), expand_vec_cmp_expr_p(), expand_vec_cond_expr_p(), gcc_assert, get_mask_type_for_scalar_type(), GET_MODE_BITSIZE(), get_vectype_for_scalar_type(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), NULL_TREE, SCALAR_TYPE_MODE, stmt_could_throw_p(), tcc_comparison, TREE_CODE, TREE_CODE_CLASS, TREE_TYPE, vect_get_internal_def(), and VECT_SCALAR_BOOLEAN_TYPE_P.
Referenced by check_bool_pattern(), and vect_recog_bool_pattern().
match.pd function to match (cond (cmp@3 a b) (convert@1 c) (convert@2 d)) with conditions: 1) @1, @2, c, d, a, b are all integral type. 2) There's single_use for both @1 and @2. 3) a, c have same precision. 4) c and @1 have different precision. 5) c, d are the same type or they can differ in sign when convert is truncation. record a and c and d and @3.
Referenced by vect_recog_cond_expr_convert_pattern().
Referenced by vect_recog_sat_add_pattern().
Referenced by vect_recog_sat_add_pattern().
Referenced by vect_recog_sat_sub_pattern().
Referenced by vect_recog_sat_trunc_pattern().
Return the proper type for converting bool VAR into an integer value or NULL_TREE if no such type exists. The type is chosen so that the converted value has the same number of elements as VAR's vector type.
References build_nonstandard_integer_type(), NULL_TREE, TREE_TYPE, vect_get_internal_def(), VECT_SCALAR_BOOLEAN_TYPE_P, and vect_use_mask_type_p().
Referenced by vect_convert_mask_for_vectype(), vect_recog_bool_pattern(), and vect_recog_mask_conversion_pattern().
|
static |
Return true if the statement described by STMT_INFO sets a boolean SSA_NAME and if we know how to vectorize this kind of statement using vector mask types.
References CASE_CONVERT, dyn_cast(), gimple_assign_rhs_code(), gimple_cond_code(), gimple_cond_lhs(), gimple_get_lhs(), is_a(), NULL, tcc_comparison, TREE_CODE, TREE_CODE_CLASS, TREE_TYPE, and VECT_SCALAR_BOOLEAN_TYPE_P.
Referenced by vect_determine_mask_precision().
|
static |
Comparison function to qsort a vector of gimple stmts after UID.
References gimple_uid().
Referenced by adjust_bool_stmts().
|
static |
Synthesize a left shift of OP by AMNT bits using a series of additions and putting the final result in DEST. Append all statements but the last into VINFO. Return the last statement.
References append_pattern_def_seq(), gcc_assert, gcc_unreachable, gimple_build_assign(), i, NULL, TREE_TYPE, and vect_recog_temp_ssa_var().
Referenced by apply_binop_and_append_stmt(), and vect_synth_mult_by_constant().
Return true iff the target has a vector optab implementing the operation CODE on type VECTYPE.
References optab_for_tree_code(), optab_handler(), optab_vector, and TYPE_MODE.
Referenced by target_supports_mult_synth_alg(), and vect_recog_mod_var_pattern().
|
static |
Verify that the target has optabs of VECTYPE to perform all the steps needed by the multiplication-by-immediate synthesis algorithm described by ALG and VAR. If SYNTH_SHIFT_P is true ensure that vector addition is present. Return true iff the target supports all the steps.
References add_variant, alg_add_factor, alg_add_t2_m, alg_add_t_m2, alg_impossible, alg_m, alg_shift, alg_sub_factor, alg_sub_t2_m, alg_sub_t_m2, alg_unknown, alg_zero, gcc_unreachable, i, negate_variant, algorithm::op, algorithm::ops, and target_has_vecop_for_code().
Referenced by vect_synth_mult_by_constant().
|
static |
Check whether NAME, an ssa-name used in STMT_VINFO, is a result of a type promotion, such that: DEF_STMT: NAME = NOP (name0) If CHECK_SIGN is TRUE, check that either both types are signed or both are unsigned.
References CONVERT_EXPR_CODE_P, gimple_assign_rhs1(), gimple_assign_rhs_code(), INTEGRAL_TYPE_P, is_gimple_assign(), TREE_TYPE, TYPE_PRECISION, TYPE_UNSIGNED, vect_constant_def, vect_external_def, vect_internal_def, and vect_is_simple_use().
Referenced by vect_recog_mixed_size_cond_pattern().
|
static |
Return the equivalent of: fold_convert (TYPE, VALUE) with the expectation that the operation will be vectorized. If new statements are needed, add them as pattern statements to STMT_INFO.
References append_pattern_def_seq(), get_vectype_for_scalar_type(), gimple_build_assign(), NULL, TREE_TYPE, useless_type_conversion_p(), and vect_recog_temp_ssa_var().
Referenced by vect_recog_gather_scatter_pattern().
|
static |
Helper method of vect_recog_cond_store_pattern, checks to see if COND_ARG is points to a load statement that reads the same data as that of STORE_VINFO.
References DR_IS_WRITE, vec_info::lookup_def(), same_data_refs(), and STMT_VINFO_DATA_REF.
Referenced by vect_recog_cond_store_pattern().
|
static |
Convert UNPROM to TYPE and return the result, adding new statements to STMT_INFO's pattern definition statements if no better way is available. VECTYPE is the vector form of TYPE. If SUBTYPE then convert the type based on the subtype.
References append_pattern_def_seq(), build_nonstandard_integer_type(), vect_unpromoted_value::caster, vect_unpromoted_value::dt, gcc_assert, get_vectype_for_scalar_type(), gimple_build_assign(), gimple_get_lhs(), gsi_insert_on_edge_immediate(), NULL, vect_unpromoted_value::op, optab_vector_mixed_sign, wi::to_widest(), TREE_CODE, TREE_TYPE, vect_unpromoted_value::type, TYPE_PRECISION, TYPE_UNSIGNED, types_compatible_p(), unsigned_type_for(), vect_external_def, vect_get_external_def_edge(), vect_recog_temp_ssa_var(), vect_split_statement(), and wide_int_to_tree().
Referenced by vect_convert_inputs(), and vect_recog_bit_insert_pattern().
|
static |
Invoke vect_convert_input for N elements of UNPROM and store the result in the corresponding elements of RESULT. If SUBTYPE then convert the type based on the subtype.
References i, and vect_convert_input().
Referenced by vect_recog_abd_pattern(), vect_recog_average_pattern(), vect_recog_dot_prod_pattern(), vect_recog_mulhs_pattern(), vect_recog_over_widening_pattern(), vect_recog_sad_pattern(), and vect_recog_widen_op_pattern().
|
static |
Return MASK if MASK is suitable for masking an operation on vectors of type VECTYPE, otherwise convert it into such a form and return the result. Associate any conversion statements with STMT_INFO's pattern.
References build_mask_conversion(), get_mask_type_for_scalar_type(), integer_type_for_mask(), and TYPE_VECTOR_SUBPARTS().
Referenced by vect_recog_cond_store_pattern(), and vect_recog_gather_scatter_pattern().
|
static |
The caller has created a (possibly empty) sequence of pattern definition statements followed by a single statement PATTERN_STMT. Cast the result of this final statement to TYPE. If a new statement is needed, add PATTERN_STMT to the end of STMT_INFO's pattern definition statements and return the new statement, otherwise return PATTERN_STMT as-is. VECITYPE is the vector form of PATTERN_STMT's result type.
References append_pattern_def_seq(), gimple_build_assign(), gimple_get_lhs(), NULL, TREE_TYPE, types_compatible_p(), and vect_recog_temp_ssa_var().
Referenced by vect_recog_abd_pattern(), vect_recog_average_pattern(), vect_recog_mulhs_pattern(), vect_recog_over_widening_pattern(), and vect_recog_widen_op_pattern().
|
static |
If STMT_INFO sets a boolean SSA_NAME, see whether we should use a vector mask type instead of a normal vector type. Record the result in STMT_INFO->mask_precision.
References as_a(), dump_enabled_p(), dump_printf_loc(), dyn_cast(), expand_vec_cmp_expr_p(), get_mask_type_for_scalar_type(), GET_MODE_BITSIZE(), get_vectype_for_scalar_type(), gimple_assign_rhs1(), gimple_assign_rhs_code(), gimple_cond_code(), gimple_cond_lhs(), gimple_num_ops(), gimple_op(), gimple_phi_arg_def(), gimple_phi_num_args(), i, is_a(), vec_info::lookup_def(), MSG_NOTE, possible_vector_mask_operation_p(), STMT_VINFO_STMT, tcc_comparison, TREE_CODE_CLASS, TREE_TYPE, TYPE_MODE, vect_location, and VECT_SCALAR_BOOLEAN_TYPE_P.
Referenced by vect_determine_precisions().
|
static |
Calculate min_output_precision for STMT_INFO.
References gimple_get_lhs(), TREE_CODE, TREE_TYPE, TYPE_PRECISION, vect_determine_min_output_precision_1(), and vect_narrowable_type_p().
Referenced by vect_determine_stmt_precisions().
|
static |
Subroutine of vect_determine_min_output_precision. Return true if we can calculate a reduced number of output bits for STMT_INFO, whose result is LHS.
References dump_enabled_p(), dump_printf_loc(), dyn_cast(), FOR_EACH_IMM_USE_FAST, gimple_assign_rhs2_ptr(), gimple_assign_rhs3_ptr(), gimple_assign_rhs_code(), is_gimple_debug(), vec_info::lookup_stmt(), MAX, MSG_NOTE, USE_STMT, and vect_location.
Referenced by vect_determine_min_output_precision().
void vect_determine_precisions | ( | vec_info * | vinfo | ) |
Walk backwards through the vectorizable region to determine the values of these fields: - min_output_precision - min_input_precision - operation_precision - operation_sign.
References vec_info::bbs, DUMP_VECT_SCOPE, gsi_end_p(), gsi_last_bb(), gsi_next(), gsi_prev(), gsi_start_bb(), gsi_start_phis(), gsi_stmt(), i, vec_info::lookup_stmt(), vec_info::nbbs, STMT_VINFO_VECTORIZABLE, vect_determine_mask_precision(), and vect_determine_stmt_precisions().
Referenced by vect_pattern_recog().
|
static |
Use range information to decide whether STMT (described by STMT_INFO) could be done in a narrower type. This is effectively a forward propagation, since it uses context-independent information that applies to all users of an SSA name.
References dump_enabled_p(), dump_printf_loc(), wide_int_storage::from(), wi::geu_p(), gimple_assign_lhs(), gimple_assign_rhs_code(), gimple_num_ops(), gimple_op(), i, MAX, wi::max(), wi::max_value(), wi::min(), wi::min_precision(), wi::min_value(), MSG_NOTE, wi::neg_p(), algorithm::op, SIGNED, generic_wide_int< storage >::to_uhwi(), wi::to_wide(), TREE_CODE, TREE_TYPE, TYPE_PRECISION, TYPE_SIGN, UNSIGNED, vect_get_range_info(), vect_location, vect_narrowable_type_p(), vect_set_min_input_precision(), vect_set_operation_type(), and vect_truncatable_operation_p().
Referenced by vect_determine_stmt_precisions().
|
static |
Use information about the users of STMT's result to decide whether STMT (described by STMT_INFO) could be done in a narrower type. This is effectively a backward propagation.
References CASE_CONVERT, dump_enabled_p(), dump_printf_loc(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_op(), wi::ltu_p(), MAX, MSG_NOTE, shift, wi::to_widest(), TREE_CODE, TREE_INT_CST_LOW, TREE_TYPE, TYPE_PRECISION, TYPE_SIGN, TYPE_UNSIGNED, vect_location, vect_narrowable_type_p(), vect_set_min_input_precision(), vect_set_operation_type(), and vect_truncatable_operation_p().
Referenced by vect_determine_stmt_precisions().
void vect_determine_stmt_precisions | ( | vec_info * | vinfo, |
stmt_vec_info | stmt_info ) |
Handle vect_determine_precisions for STMT_INFO, given that we have already done so for the users of its result.
References dyn_cast(), vect_determine_min_output_precision(), vect_determine_precisions_from_range(), and vect_determine_precisions_from_users().
Referenced by vect_determine_precisions().
|
static |
Round bit precision PRECISION up to a full element.
References ceil_log2(), and MAX.
Referenced by vect_joust_widened_integer(), vect_recog_average_pattern(), vect_recog_mulhs_pattern(), vect_recog_over_widening_pattern(), and vect_set_operation_type().
The caller wants to perform new operations on vect_external variable VAR, so that the result of the operations would also be vect_external. Return the edge on which the operations can be performed, if one exists. Return null if the operations should instead be treated as part of the pattern that needs them.
References CDI_DOMINATORS, dominated_by_p(), dyn_cast(), gimple_bb(), loop_preheader_edge(), NULL, SSA_NAME_DEF_STMT, and SSA_NAME_IS_DEFAULT_DEF.
Referenced by vect_convert_input(), and vect_recog_rotate_pattern().
|
static |
If OP is defined by a statement that's being considered for vectorization, return information about that statement, otherwise return NULL.
References vec_info::lookup_def(), NULL, STMT_VINFO_DEF_TYPE, vect_internal_def, and vect_stmt_to_vectorize().
Referenced by check_bool_pattern(), integer_type_for_mask(), vect_recog_absolute_difference(), vect_recog_average_pattern(), vect_recog_dot_prod_pattern(), vect_recog_mulhs_pattern(), vect_recog_sad_pattern(), vect_recog_vector_vector_shift_pattern(), vect_recog_widen_abd_pattern(), and vect_widened_op_tree().
|
static |
STMT_INFO is a load or store. If the load or store is conditional, return the boolean condition under which it occurs, otherwise return null.
References dyn_cast(), gcc_assert, gcc_unreachable, gimple_assign_single_p(), gimple_call_arg(), gimple_call_internal_fn(), internal_fn_mask_index(), and NULL_TREE.
Referenced by vect_recog_gather_scatter_pattern().
TODO: Note the vectorizer still builds COND_EXPRs with GENERIC compares in the first operand. Disentangling this is future work, the IL is properly transfered to VEC_COND_EXPRs with separate compares.
Return true if we have a useful VR_RANGE range for VAR, storing it in *MIN_VALUE and *MAX_VALUE if so. Note the range in the dump files.
References cfun, dump_enabled_p(), dump_generic_expr_loc(), dump_hex(), dump_printf(), get_legacy_range(), get_nonzero_bits(), get_range_query(), intersect_range_with_nonzero_bits(), MSG_NOTE, path_range_query::range_of_expr(), irange::set_varying(), TDF_SLIM, wi::to_wide(), TREE_TYPE, TYPE_SIGN, vrange::undefined_p(), vect_location, and VR_RANGE.
Referenced by supportable_indirect_convert_operation(), vect_determine_precisions_from_range(), and vectorizable_conversion().
gimple * vect_gimple_build | ( | tree | lhs, |
code_helper | ch, | ||
tree | op0, | ||
tree | op1 ) |
Build a GIMPLE_ASSIGN or GIMPLE_CALL with the tree_code, or internal_fn contained in ch, respectively.
References as_internal_fn(), gcc_assert, gimple_build_assign(), gimple_build_call_internal(), gimple_call_set_lhs(), code_helper::is_internal_fn(), code_helper::is_tree_code(), and NULL_TREE.
Referenced by vect_create_half_widening_stmts(), vect_create_vectorized_demotion_stmts(), vect_gen_widened_results_half(), vect_recog_widen_op_pattern(), vectorizable_call(), and vectorizable_conversion().
|
static |
Associate pattern statement PATTERN_STMT with ORIG_STMT_INFO and return the pattern statement's stmt_vec_info. Set its vector type to VECTYPE if it doesn't have one already.
References vec_info::add_stmt(), gcc_assert, gimple_bb(), gimple_set_bb(), is_a(), vec_info::lookup_stmt(), NULL, STMT_VINFO_DEF_TYPE, STMT_VINFO_RELATED_STMT, STMT_VINFO_TYPE, STMT_VINFO_VECTYPE, vect_use_mask_type_p(), and VECTOR_BOOLEAN_TYPE_P.
Referenced by vect_mark_pattern_stmts(), vect_set_pattern_stmt(), and vect_split_statement().
|
static |
OP is an integer operand to an operation that returns TYPE, and we want to treat the operation as a widening one. So far we can treat it as widening from *COMMON_TYPE. Return true if OP is suitable for such a widening operation, either widening from *COMMON_TYPE or from some supertype of it. Update *COMMON_TYPE to the supertype in the latter case. SHIFT_P is true if OP is a shift amount.
References build_nonstandard_integer_type(), wi::leu_p(), wi::min_precision(), wi::to_widest(), TREE_INT_CST_LOW, TYPE_PRECISION, TYPE_SIGN, TYPE_UNSIGNED, and vect_element_precision().
Referenced by vect_widened_op_tree().
Return true if the common supertype of NEW_TYPE and *COMMON_TYPE is narrower than type, storing the supertype in *COMMON_TYPE if so.
References build_nonstandard_integer_type(), MAX, TYPE_PRECISION, TYPE_UNSIGNED, and types_compatible_p().
Referenced by vect_widened_op_tree().
|
static |
If OP is a vectorizable SSA name, strip a sequence of integer conversions to reach some vectorizable inner operand OP', continuing as long as it is possible to convert OP' back to OP using a possible sign change followed by a possible promotion P. Return this OP', or null if OP is not a vectorizable SSA name. If there is a promotion P, describe its input in UNPROM, otherwise describe OP' in UNPROM. If SINGLE_USE_P is nonnull, set *SINGLE_USE_P to false if any of the SSA names involved have more than one user. A successful return means that it is possible to go from OP' to OP via UNPROM. The cast from OP' to UNPROM is at most a sign change, whereas the cast from UNPROM to OP might be a promotion, a sign change, or a nop. E.g. say we have: signed short *ptr = ...; signed short C = *ptr; unsigned short B = (unsigned short) C; // sign change signed int A = (signed int) B; // unsigned promotion ...possible other uses of A... unsigned int OP = (unsigned int) A; // sign change In this case it's possible to go directly from C to OP using: OP = (unsigned int) (unsigned short) C; +------------+ +--------------+ promotion sign change so OP' would be C. The input to the promotion is B, so UNPROM would describe B.
References CONVERT_EXPR_CODE_P, dyn_cast(), gimple_assign_rhs1(), gimple_assign_rhs_code(), has_single_use(), INTEGRAL_TYPE_P, NULL, NULL_TREE, vect_unpromoted_value::set_op(), STMT_VINFO_RELATED_STMT, TREE_CODE, TREE_TYPE, vect_unpromoted_value::type, TYPE_PRECISION, TYPE_SIGN, TYPE_UNSIGNED, and vect_is_simple_use().
Referenced by vect_recog_absolute_difference(), vect_recog_average_pattern(), vect_recog_cast_forwprop_pattern(), vect_recog_dot_prod_pattern(), vect_recog_mulhs_pattern(), vect_recog_over_widening_pattern(), vect_recog_popcount_clz_ctz_ffs_pattern(), vect_recog_sad_pattern(), vect_recog_sat_sub_pattern_transform(), vect_recog_widen_abd_pattern(), vect_recog_widen_sum_pattern(), and vect_widened_op_tree().
void vect_mark_pattern_stmts | ( | vec_info * | vinfo, |
stmt_vec_info | orig_stmt_info, | ||
gimple * | pattern_stmt, | ||
tree | pattern_vectype ) |
Mark statements that are involved in a pattern.
References dump_enabled_p(), dump_printf_loc(), gcc_assert, gcc_unreachable, gimple_extract_op(), gimple_get_lhs(), gimple_set_lhs(), gsi_end_p(), gsi_for_stmt(), gsi_insert_before_without_update(), gsi_insert_seq_before_without_update(), gsi_next(), gsi_none(), gsi_remove(), GSI_SAME_STMT, gsi_start(), gsi_stmt(), i, is_a(), is_pattern_stmt_p(), vec_info::lookup_stmt(), MSG_NOTE, NULL, gimple_match_op::num_ops, gimple_match_op::ops, si, STMT_VINFO_DEF_TYPE, STMT_VINFO_PATTERN_DEF_SEQ, STMT_VINFO_REDUC_IDX, STMT_VINFO_RELATED_STMT, vect_condition_def, vect_init_pattern_stmt(), vect_internal_def, vect_location, and vect_set_pattern_stmt().
Referenced by vect_pattern_recog_1().
Return true if TYPE is a non-boolean integer type. These are the types that we want to consider for narrowing.
References INTEGRAL_TYPE_P, and VECT_SCALAR_BOOLEAN_TYPE_P.
Referenced by vect_determine_min_output_precision(), vect_determine_precisions_from_range(), and vect_determine_precisions_from_users().
|
static |
Report that we've found an instance of pattern PATTERN in statement STMT.
References dump_enabled_p(), dump_printf_loc(), MSG_NOTE, and vect_location.
Referenced by vect_recog_abd_pattern(), vect_recog_average_pattern(), vect_recog_bit_insert_pattern(), vect_recog_bitfield_ref_pattern(), vect_recog_bool_pattern(), vect_recog_cast_forwprop_pattern(), vect_recog_cond_expr_convert_pattern(), vect_recog_cond_store_pattern(), vect_recog_ctz_ffs_pattern(), vect_recog_divmod_pattern(), vect_recog_dot_prod_pattern(), vect_recog_gather_scatter_pattern(), vect_recog_gcond_pattern(), vect_recog_mask_conversion_pattern(), vect_recog_mixed_size_cond_pattern(), vect_recog_mod_var_pattern(), vect_recog_mulhs_pattern(), vect_recog_mult_pattern(), vect_recog_over_widening_pattern(), vect_recog_popcount_clz_ctz_ffs_pattern(), vect_recog_rotate_pattern(), vect_recog_sad_pattern(), vect_recog_sat_add_pattern(), vect_recog_sat_sub_pattern(), vect_recog_vector_vector_shift_pattern(), vect_recog_widen_abd_pattern(), vect_recog_widen_op_pattern(), and vect_recog_widen_sum_pattern().
void vect_pattern_recog | ( | vec_info * | vinfo | ) |
Function vect_pattern_recog Input: LOOP_VINFO - a struct_loop_info of a loop in which we want to look for computation idioms. Output - for each computation idiom that is detected we create a new stmt that provides the same functionality and that can be vectorized. We also record some information in the struct_stmt_info of the relevant stmts, as explained below: At the entry to this function we have the following stmts, with the following initial value in the STMT_VINFO fields: stmt in_pattern_p related_stmt vec_stmt S1: a_i = .... - - - S2: a_2 = ..use(a_i).. - - - S3: a_1 = ..use(a_2).. - - - S4: a_0 = ..use(a_1).. - - - S5: ... = ..use(a_0).. - - - Say the sequence {S1,S2,S3,S4} was detected as a pattern that can be represented by a single stmt. We then: - create a new stmt S6 equivalent to the pattern (the stmt is not inserted into the code) - fill in the STMT_VINFO fields as follows: in_pattern_p related_stmt vec_stmt S1: a_i = .... - - - S2: a_2 = ..use(a_i).. - - - S3: a_1 = ..use(a_2).. - - - S4: a_0 = ..use(a_1).. true S6 - '---> S6: a_new = .... - S4 - S5: ... = ..use(a_0).. - - - (the last stmt in the pattern (S4) and the new pattern stmt (S6) point to each other through the RELATED_STMT field). S6 will be marked as relevant in vect_mark_stmts_to_be_vectorized instead of S4 because it will replace all its uses. Stmts {S1,S2,S3} will remain irrelevant unless used by stmts other than S4. If vectorization succeeds, vect_transform_stmt will skip over {S1,S2,S3} (because they are marked as irrelevant). It will vectorize S6, and record a pointer to the new vector stmt VS6 from S6 (as usual). S4 will be skipped, and S5 will be vectorized as usual: in_pattern_p related_stmt vec_stmt S1: a_i = .... - - - S2: a_2 = ..use(a_i).. - - - S3: a_1 = ..use(a_2).. - - - > VS6: va_new = .... - - - S4: a_0 = ..use(a_1).. true S6 VS6 '---> S6: a_new = .... - S4 VS6 > VS5: ... = ..vuse(va_new).. - - - S5: ... = ..use(a_0).. - - - DCE could then get rid of {S1,S2,S3,S4,S5} (if their defs are not used elsewhere), and we'll end up with: VS6: va_new = .... VS5: ... = ..vuse(va_new).. In case of more than one pattern statements, e.g., widen-mult with intermediate type: S1 a_t = ; S2 a_T = (TYPE) a_t; '--> S3: a_it = (interm_type) a_t; S4 prod_T = a_T * CONST; '--> S5: prod_T' = a_it w* CONST; there may be other users of a_T outside the pattern. In that case S2 will be marked as relevant (as well as S3), and both S2 and S3 will be analyzed and vectorized. The vector stmt VS2 will be recorded in S2, and VS3 will be recorded in S3.
References vec_info::bbs, DUMP_VECT_SCOPE, gsi_end_p(), gsi_next(), gsi_start_bb(), gsi_stmt(), i, vec_info::lookup_stmt(), vec_info::nbbs, si, vec_info::stmt_vec_info_ro, STMT_VINFO_VECTORIZABLE, vect_determine_precisions(), vect_pattern_recog_1(), and vect_vect_recog_func_ptrs.
Referenced by vect_analyze_loop_2(), and vect_slp_analyze_bb_1().
|
static |
Function vect_pattern_recog_1 Input: PATTERN_RECOG_FUNC: A pointer to a function that detects a certain computation pattern. STMT_INFO: A stmt from which the pattern search should start. If PATTERN_RECOG_FUNC successfully detected the pattern, it creates a sequence of statements that has the same functionality and can be used to replace STMT_INFO. It returns the last statement in the sequence and adds any earlier statements to STMT_INFO's STMT_VINFO_PATTERN_DEF_SEQ. PATTERN_RECOG_FUNC also sets *TYPE_OUT to the vector type of the final statement, having first checked that the target supports the new operation in that type. This function also does some bookkeeping, as explained in the documentation for vect_recog_pattern.
References dump_enabled_p(), dump_printf_loc(), vect_recog_func::fn, gcc_assert, gsi_end_p(), gsi_next(), gsi_start(), gsi_stmt(), vec_info::lookup_stmt(), MSG_NOTE, vect_recog_func::name, NULL, STMT_VINFO_IN_PATTERN_P, STMT_VINFO_PATTERN_DEF_SEQ, vect_location, vect_mark_pattern_stmts(), and vect_pattern_recog_1().
Referenced by vect_pattern_recog(), and vect_pattern_recog_1().
|
static |
Return true if STMT_VINFO describes a reduction for which reassociation is allowed. If STMT_INFO is part of a group, assume that it's part of a reduction chain and optimistically assume that all statements except the last allow reassociation. Also require it to have code CODE and to be a reduction in the outermost loop. When returning true, store the operands in *OP0_OUT and *OP1_OUT.
References commutative_tree_code(), dyn_cast(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), LOOP_VINFO_LOOP, needs_fold_left_reduction_p(), nested_in_vect_loop_p(), NULL, REDUC_GROUP_FIRST_ELEMENT, STMT_VINFO_DEF_TYPE, STMT_VINFO_REDUC_IDX, TREE_TYPE, and vect_reduction_def.
Referenced by vect_recog_dot_prod_pattern(), vect_recog_sad_pattern(), and vect_recog_widen_sum_pattern().
|
static |
Function vect_recog_abd_pattern Try to find the following ABsolute Difference (ABD) or widening ABD (WIDEN_ABD) pattern: TYPE1 x; TYPE2 y; TYPE3 x_cast = (TYPE3) x; // widening or no-op TYPE3 y_cast = (TYPE3) y; // widening or no-op TYPE3 diff = x_cast - y_cast; TYPE4 diff_cast = (TYPE4) diff; // widening or no-op TYPE5 abs = ABS(U)_EXPR <diff_cast>; WIDEN_ABD exists to optimize the case where TYPE4 is at least twice as wide as TYPE3. Input: * STMT_VINFO: The stmt from which the pattern search begins Output: * 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, principally: out = IFN_ABD (x, y) out = IFN_WIDEN_ABD (x, y)
References build_nonstandard_integer_type(), direct_internal_fn_supported_p(), dyn_cast(), get_vectype_for_scalar_type(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_build_call_internal(), gimple_call_set_lhs(), gimple_location(), gimple_set_location(), NULL, vect_unpromoted_value::op, OPTIMIZE_FOR_SPEED, signed_type_for(), STMT_VINFO_STMT, supportable_widening_operation(), TREE_TYPE, TYPE_PRECISION, TYPE_UNSIGNED, unsigned_type_for(), vect_convert_inputs(), vect_convert_output(), vect_pattern_detected(), vect_recog_absolute_difference(), and vect_recog_temp_ssa_var().
|
static |
Look for the following pattern X = x[i] Y = y[i] DIFF = X - Y DAD = ABS_EXPR<DIFF> ABS_STMT should point to a statement of code ABS_EXPR or ABSU_EXPR. HALF_TYPE and UNPROM will be set should the statement be found to be a widened operation. DIFF_STMT will be set to the MINUS_EXPR statement that precedes the ABS_STMT if it is a MINUS_EXPR..
References ANY_INTEGRAL_TYPE_P, dyn_cast(), gimple_assign_rhs1(), gimple_assign_rhs_code(), STMT_VINFO_STMT, TREE_TYPE, vect_unpromoted_value::type, TYPE_OVERFLOW_UNDEFINED, TYPE_OVERFLOW_WRAPS, TYPE_PRECISION, TYPE_UNSIGNED, vect_get_internal_def(), vect_look_through_possible_promotion(), and vect_widened_op_tree().
Referenced by vect_recog_abd_pattern(), and vect_recog_sad_pattern().
|
static |
Recognize the patterns: ATYPE a; // narrower than TYPE BTYPE b; // narrower than TYPE (1) TYPE avg = ((TYPE) a + (TYPE) b) >> 1; or (2) TYPE avg = ((TYPE) a + (TYPE) b + 1) >> 1; where only the bottom half of avg is used. Try to transform them into: (1) NTYPE avg' = .AVG_FLOOR ((NTYPE) a, (NTYPE) b); or (2) NTYPE avg' = .AVG_CEIL ((NTYPE) a, (NTYPE) b); followed by: TYPE avg = (TYPE) avg'; where NTYPE is no wider than half of TYPE. Since only the bottom half of avg is used, all or part of the cast of avg' should become redundant. If there is no target support available, generate code to distribute rshift over plus and add a carry.
References append_pattern_def_seq(), build_nonstandard_integer_type(), build_one_cst(), direct_internal_fn_supported_p(), dump_enabled_p(), dump_printf_loc(), dyn_cast(), g, get_vectype_for_scalar_type(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_build_assign(), gimple_build_call_internal(), gimple_call_set_lhs(), gimple_location(), gimple_set_location(), i, integer_onep(), INTEGRAL_TYPE_P, MSG_NOTE, NULL, optab_default, optab_for_tree_code(), optab_scalar, OPTIMIZE_FOR_SPEED, TREE_TYPE, TYPE_PRECISION, TYPE_UNSIGNED, vect_convert_inputs(), vect_convert_output(), vect_element_precision(), vect_get_internal_def(), vect_location, vect_look_through_possible_promotion(), vect_pattern_detected(), vect_recog_temp_ssa_var(), and vect_widened_op_tree().
|
static |
Function vect_recog_bit_insert_pattern Try to find the following pattern: written = BIT_INSERT_EXPR (container, value, bitpos); Input: * STMT_VINFO: The stmt we want to replace. Output: * TYPE_OUT: The vector 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: value = (container_type) value; // Make sure shifted = value << bitpos; // Shift value into place masked = shifted & (mask << bitpos); // Mask off the non-relevant bits in // the 'to-write value'. cleared = container & ~(mask << bitpos); // Clearing the bits we want to // write to from the value we want // to write to. written = cleared | masked; // Write bits. where mask = ((1 << TYPE_PRECISION (value)) - 1), a mask to keep the number of bits corresponding to the real size of the bitfield value we are writing to. The shifting is always optional depending on whether bitpos != 0.
References append_pattern_def_seq(), build_int_cst(), dyn_cast(), get_vectype_for_scalar_type(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs3(), gimple_assign_rhs_code(), gimple_build(), gimple_build_assign(), gimple_get_lhs(), gimple_seq_empty_p(), gimple_seq_first_stmt(), INTEGRAL_TYPE_P, NULL, vect_unpromoted_value::set_op(), shift, wi::shifted_mask(), STMT_VINFO_VECTYPE, tree_fits_uhwi_p(), tree_to_uhwi(), TREE_TYPE, TYPE_PRECISION, TYPE_SIZE, useless_type_conversion_p(), vect_convert_input(), vect_internal_def, vect_pattern_detected(), vect_recog_temp_ssa_var(), and wide_int_to_tree().
|
static |
Function vect_recog_bitfield_ref_pattern Try to find the following pattern: bf_value = BIT_FIELD_REF (container, bitsize, bitpos); result = (type_out) bf_value; or if (BIT_FIELD_REF (container, bitsize, bitpos) `cmp` <constant>) where type_out is a non-bitfield type, that is to say, it's precision matches 2^(TYPE_SIZE(type_out) - (TYPE_UNSIGNED (type_out) ? 1 : 2)). Input: * STMT_VINFO: The stmt from which the pattern search begins. here it starts with: result = (type_out) bf_value; or if (BIT_FIELD_REF (container, bitsize, bitpos) `cmp` <constant>) Output: * TYPE_OUT: The vector 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. If the precision of type_out is bigger than the precision type of _1 we perform the widening before the shifting, since the new precision will be large enough to shift the value and moving widening operations up the statement chain enables the generation of widening loads. If we are widening and the operation after the pattern is an addition then we mask first and shift later, to enable the generation of shifting adds. In the case of narrowing we will always mask first, shift last and then perform a narrowing operation. This will enable the generation of narrowing shifts. Widening with mask first, shift later: container = (type_out) container; masked = container & (((1 << bitsize) - 1) << bitpos); result = masked >> bitpos; Widening with shift first, mask last: container = (type_out) container; shifted = container >> bitpos; result = shifted & ((1 << bitsize) - 1); Narrowing: masked = container & (((1 << bitsize) - 1) << bitpos); result = masked >> bitpos; result = (type_out) result; If the bitfield is signed and it's wider than type_out, we need to keep the result sign-extended: container = (type) container; masked = container << (prec - bitsize - bitpos); result = (type_out) (masked >> (prec - bitsize)); Here type is the signed variant of the wider of type_out and the type of container. The shifting is always optional depending on whether bitpos != 0. When the original bitfield was inside a gcond then an new gcond is also generated with the newly `result` as the operand to the comparison.
References append_pattern_def_seq(), bit_field_offset(), bit_field_size(), boolean_type_node, build_int_cst(), build_zero_cst(), CONVERT_EXPR_CODE_P, dyn_cast(), fold_convert, get_vectype_for_scalar_type(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs_code(), gimple_build_assign(), gimple_build_cond(), gimple_cond_code(), gimple_cond_lhs(), gimple_cond_rhs(), gimple_get_lhs(), gimple_signed_type(), INTEGRAL_TYPE_P, is_gimple_assign(), is_pattern_stmt_p(), wi::mask(), NULL, NULL_TREE, wi::shifted_mask(), single_imm_use(), sizetype, SSA_NAME_DEF_STMT, STMT_VINFO_STMT, STMT_VINFO_VECTYPE, poly_int< N, C >::to_constant(), TREE_CODE, tree_fits_uhwi_p(), TREE_OPERAND, tree_to_uhwi(), TREE_TYPE, truth_type_for(), TYPE_MODE, TYPE_PRECISION, TYPE_SIZE, TYPE_UNSIGNED, useless_type_conversion_p(), vect_pattern_detected(), vect_recog_temp_ssa_var(), and wide_int_to_tree().
|
static |
Function vect_recog_bool_pattern Try to find pattern like following: bool a_b, b_b, c_b, d_b, e_b; TYPE f_T; loop: S1 a_b = x1 CMP1 y1; S2 b_b = x2 CMP2 y2; S3 c_b = a_b & b_b; S4 d_b = x3 CMP3 y3; S5 e_b = c_b | d_b; S6 f_T = (TYPE) e_b; where type 'TYPE' is an integral type. Or a similar pattern ending in S6 f_Y = e_b ? r_Y : s_Y; as results from if-conversion of a complex condition. Input: * STMT_VINFO: The stmt at the end from which the pattern search begins, i.e. cast of a bool to an integer type. Output: * TYPE_OUT: The type of the output of this pattern. * Return value: A new stmt that will be used to replace the pattern. Assuming size of TYPE is the same as size of all comparisons (otherwise some casts would be added where needed), the above sequence we create related pattern stmts: S1' a_T = x1 CMP1 y1 ? 1 : 0; S3' c_T = x2 CMP2 y2 ? a_T : 0; S4' d_T = x3 CMP3 y3 ? 1 : 0; S5' e_T = c_T | d_T; S6' f_T = e_T; Instead of the above S3' we could emit: S2' b_T = x2 CMP2 y2 ? 1 : 0; S3' c_T = a_T | b_T; but the above is more efficient.
References vec_info::add_stmt(), adjust_bool_stmts(), append_inv_pattern_def_seq(), append_pattern_def_seq(), boolean_type_node, build1(), build_all_ones_cst(), build_int_cst(), build_nonstandard_integer_type(), build_zero_cst(), check_bool_pattern(), CONVERT_EXPR_CODE_P, get_mask_type_for_scalar_type(), get_vectype_for_scalar_type(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs3(), gimple_assign_rhs_code(), gimple_build_assign(), integer_type_for_mask(), INTEGRAL_TYPE_P, is_gimple_assign(), vec_info::move_dr(), NULL, NULL_TREE, STMT_VINFO_DATA_REF, TREE_CODE, TREE_OPERAND, tree_to_poly_uint64(), TREE_TYPE, truth_type_for(), TYPE_MODE, TYPE_SIZE, TYPE_UNSIGNED, TYPE_VECTOR_SUBPARTS(), useless_type_conversion_p(), vect_constant_def, vect_external_def, vect_is_simple_use(), vect_pattern_detected(), vect_recog_temp_ssa_var(), VECT_SCALAR_BOOLEAN_TYPE_P, vector_element_size, and VECTOR_MODE_P.
|
static |
References append_pattern_def_seq(), direct_internal_fn_supported_p(), get_vectype_for_scalar_type(), gimple_build_assign(), gimple_build_call_internal(), gimple_call_set_lhs(), gimple_call_set_nothrow(), gimple_location(), gimple_set_location(), NULL, NULL_TREE, OPTIMIZE_FOR_BOTH, STMT_VINFO_STMT, TREE_TYPE, types_compatible_p(), and vect_recog_temp_ssa_var().
Referenced by vect_recog_sat_add_pattern(), and vect_recog_sat_sub_pattern().
|
static |
Recognize cases in which the input to a cast is wider than its output, and the input is fed by a widening operation. Fold this by removing the unnecessary intermediate widening. E.g.: unsigned char a; unsigned int b = (unsigned int) a; unsigned short c = (unsigned short) b; --> unsigned short c = (unsigned short) a; Although this is rare in input IR, it is an expected side-effect of the over-widening pattern above. This is beneficial also for integer-to-float conversions, if the widened integer has more bits than the float, and if the unwidened input doesn't.
References CONVERT_EXPR_CODE_P, dyn_cast(), GET_MODE_BITSIZE(), get_vectype_for_scalar_type(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs_code(), gimple_build_assign(), gimple_location(), gimple_set_location(), INTEGRAL_TYPE_P, is_a(), NULL, vect_unpromoted_value::op, TREE_TYPE, vect_unpromoted_value::type, TYPE_MODE, TYPE_PRECISION, TYPE_SIGN, vect_look_through_possible_promotion(), vect_pattern_detected(), vect_recog_temp_ssa_var(), and VECT_SCALAR_BOOLEAN_TYPE_P.
|
static |
Function vect_recog_cond_expr_convert Try to find the following pattern: TYPE_AB A,B; TYPE_CD C,D; TYPE_E E; TYPE_E op_true = (TYPE_E) A; TYPE_E op_false = (TYPE_E) B; E = C cmp D ? op_true : op_false; where TYPE_PRECISION (TYPE_E) != TYPE_PRECISION (TYPE_CD); TYPE_PRECISION (TYPE_AB) == TYPE_PRECISION (TYPE_CD); single_use of op_true and op_false. TYPE_AB could differ in sign when (TYPE_E) A is a truncation. Input: * STMT_VINFO: The stmt from which the pattern search begins. here it starts with E = c cmp D ? op_true : op_false; Output: TYPE1 E' = C cmp D ? A : B; TYPE3 E = (TYPE3) E'; There may extra nop_convert for A or B to handle different signness. * TYPE_OUT: The vector 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: E = (TYPE3)E'; E' = C cmp D ? A : B; is recorded in pattern definition statements;
References append_pattern_def_seq(), build3(), dump_enabled_p(), dump_printf_loc(), dyn_cast(), get_vectype_for_scalar_type(), gimple_assign_lhs(), gimple_build_assign(), gimple_cond_expr_convert_p(), MSG_NOTE, NULL, STMT_VINFO_VECTYPE, TREE_TYPE, type(), TYPE_SIGN, vect_location, vect_pattern_detected(), and vect_recog_temp_ssa_var().
|
static |
Function vect_recog_cond_store_pattern Try to find the following pattern: x = *_3; c = a CMP b; y = c ? t_20 : x; *_3 = y; where the store of _3 happens on a conditional select on a value loaded from the same location. In such case we can elide the initial load if MASK_STORE is supported and instead only conditionally write out the result. The pattern produces for the above: c = a CMP b; .MASK_STORE (_3, c, t_20) Input: * STMT_VINFO: The stmt from which the pattern search begins. In the example, when this function is called with _3 then the search begins. Output: * TYPE_OUT: The type of the output of this pattern. * Return value: A new stmt that will be used to replace the sequence.
References vec_info::add_stmt(), append_pattern_def_seq(), boolean_type_node, build_fold_addr_expr, build_int_cst(), can_vec_mask_load_store_p(), DR_IS_READ, DR_REF, dyn_cast(), get_mask_type_for_scalar_type(), get_object_alignment(), get_vectype_for_scalar_type(), gimple_arg(), gimple_assign_rhs1(), gimple_assign_rhs_code(), gimple_build_assign(), gimple_build_call_internal(), gimple_location(), gimple_set_location(), gimple_store_p(), gimple_vuse(), vec_info::lookup_def(), may_be_nonaddressable_p(), vec_info::move_dr(), NULL, NULL_TREE, reference_alias_ptr_type(), SSA_NAME_DEF_STMT, STMT_VINFO_DATA_REF, STMT_VINFO_STMT, targetm, TREE_CODE, TREE_TYPE, TYPE_MODE, vect_cond_store_pattern_same_ref(), vect_convert_mask_for_vectype(), vect_pattern_detected(), vect_recog_temp_ssa_var(), vect_stmt_to_vectorize(), VECTOR_MODE_P, and VECTOR_TYPE_P.
|
static |
Function vect_recog_ctz_ffs_pattern Try to find the following pattern: TYPE1 A; TYPE1 B; B = __builtin_ctz{,l,ll} (A); or B = __builtin_ffs{,l,ll} (A); Input: * STMT_VINFO: The stmt from which the pattern search begins. here it starts with B = __builtin_* (A); Output: * TYPE_OUT: The vector 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, using clz or popcount builtins.
References append_pattern_def_seq(), boolean_type_node, build2_loc(), build_int_cst(), build_zero_cst(), CLZ_DEFINED_VALUE_AT_ZERO, CTZ_DEFINED_VALUE_AT_ZERO, direct_internal_fn_supported_p(), dump_enabled_p(), dump_printf_loc(), get_vectype_for_scalar_type(), gimple_build_assign(), gimple_build_call_internal(), gimple_call_arg(), gimple_call_combined_fn(), gimple_call_internal_p(), gimple_call_lhs(), gimple_call_num_args(), gimple_call_set_lhs(), gimple_location(), gimple_set_location(), integer_type_node, INTEGRAL_TYPE_P, is_gimple_call(), MSG_NOTE, NULL, OPTIMIZE_FOR_SPEED, SCALAR_INT_TYPE_MODE, TREE_CODE, tree_to_shwi(), TREE_TYPE, type_has_mode_precision_p(), TYPE_PRECISION, TYPE_UNSIGNED, unsigned_type_for(), vect_location, vect_pattern_detected(), and vect_recog_temp_ssa_var().
Referenced by vect_recog_popcount_clz_ctz_ffs_pattern().
|
static |
Detect a signed division by a constant that wouldn't be otherwise vectorized: type a_t, b_t; S1 a_t = b_t / N; where type 'type' is an integral type and N is a constant. Similarly handle modulo by a constant: S4 a_t = b_t % N; Input/Output: * STMT_VINFO: The stmt from which the pattern search begins, i.e. the division stmt. S1 is replaced by if N is a power of two constant and type is signed: S3 y_t = b_t < 0 ? N - 1 : 0; S2 x_t = b_t + y_t; S1' a_t = x_t >> log2 (N); S4 is replaced if N is a power of two constant and type is signed by (where *_T temporaries have unsigned type): S9 y_T = b_t < 0 ? -1U : 0U; S8 z_T = y_T >> (sizeof (type_t) * CHAR_BIT - log2 (N)); S7 z_t = (type) z_T; S6 w_t = b_t + z_t; S5 x_t = w_t & (N - 1); S4' a_t = x_t - z_t; Output: * TYPE_OUT: The type of the output of this pattern. * Return value: A new stmt that will be used to replace the division S1 or modulo S4 stmt.
References wi::add(), append_pattern_def_seq(), boolean_type_node, build2(), build_int_cst(), build_nonstandard_integer_type(), can_mult_highpart_p(), cfun, choose_multiplier(), compare_tree_int(), ctz_or_zero(), direct_internal_fn_supported_p(), wi::exact_log2(), fold_build2, gcc_assert, GET_MODE_BITSIZE(), GET_MODE_MASK, get_range_query(), get_vectype_for_scalar_type(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_bb(), gimple_build_assign(), gimple_build_call_internal(), gimple_call_set_lhs(), gimple_location(), gimple_set_location(), HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT_1U, HOST_WIDE_INT_M1U, integer_one_node, integer_pow2p(), integer_zerop(), is_gimple_assign(), wi::lshift(), wi::neg_p(), NULL, NULL_TREE, optab_default, optab_for_tree_code(), optab_handler(), optimize_bb_for_size_p(), OPTIMIZE_FOR_SPEED, wi::OVF_NONE, pow(), r, gimple_ranger::range_of_expr(), path_range_query::range_of_expr(), ranger, SCALAR_INT_TYPE_MODE, shift, wi::shwi(), SSA_NAME_DEF_STMT, targetm, wi::to_wide(), TREE_CODE, TREE_INT_CST_LOW, tree_int_cst_sgn(), tree_log2(), TREE_TYPE, type_has_mode_precision_p(), TYPE_MODE, TYPE_PRECISION, TYPE_SIGN, TYPE_UNSIGNED, uniform_integer_cst_p(), unknown_optab, UNSIGNED, vect_pattern_detected(), vect_recog_temp_ssa_var(), and wide_int_to_tree().
|
static |
Function vect_recog_dot_prod_pattern Try to find the following pattern: type1a x_t type1b y_t; TYPE1 prod; TYPE2 sum = init; loop: sum_0 = phi <init, sum_1> S1 x_t = ... S2 y_t = ... S3 x_T = (TYPE1) x_t; S4 y_T = (TYPE1) y_t; S5 prod = x_T * y_T; [S6 prod = (TYPE2) prod; #optional] S7 sum_1 = prod + sum_0; where 'TYPE1' is exactly double the size of type 'type1a' and 'type1b', the sign of 'TYPE1' must be one of 'type1a' or 'type1b' but the sign of 'type1a' and 'type1b' can differ. Input: * STMT_VINFO: The stmt from which the pattern search begins. In the example, when this function is called with S7, the pattern {S3,S4,S5,S6,S7} will be detected. Output: * 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: WIDEN_DOT_PRODUCT <x_t, y_t, sum_0> Note: The dot-prod idiom is a widening reduction pattern that is vectorized without preserving all the intermediate results. It produces only N/2 (widened) results (by summing up pairs of intermediate results) rather than all N results. Therefore, we cannot allow this pattern when we want to get all the results and in the correct order (as is the case when this computation is in an inner-loop nested in an outer-loop that us being vectorized).
References gimple_build_assign(), gimple_get_lhs(), NULL, optab_vector, optab_vector_mixed_sign, signed_or_unsigned_type_for(), signed_type_for(), TREE_TYPE, type(), vect_unpromoted_value::type, TYPE_PRECISION, TYPE_SIGN, TYPE_UNSIGNED, vect_convert_inputs(), vect_get_internal_def(), vect_look_through_possible_promotion(), vect_pattern_detected(), vect_reassociating_reduction_p(), vect_recog_temp_ssa_var(), vect_supportable_conv_optab_p(), and vect_widened_op_tree().
|
static |
Try to convert STMT_INFO into a call to a gather load or scatter store internal function. Return the final statement on success and set *TYPE_OUT to the vector type being loaded or stored. This function only handles gathers and scatters that were recognized as such from the outset (indicated by STMT_VINFO_GATHER_SCATTER_P).
References vec_info::add_stmt(), gather_scatter_info::base, build_int_cst(), build_zero_cst(), DR_IS_READ, dyn_cast(), gather_scatter_info::element_type, get_vectype_for_scalar_type(), gimple_build_call_internal(), gimple_call_set_lhs(), gimple_call_set_nothrow(), gather_scatter_info::ifn, vec_info::move_dr(), NULL, gather_scatter_info::offset, offset, gather_scatter_info::offset_vectype, gather_scatter_info::scale, size_int, STMT_VINFO_DATA_REF, STMT_VINFO_GATHER_SCATTER_P, STMT_VINFO_VECTYPE, TREE_TYPE, truth_type_for(), vect_add_conversion_to_pattern(), vect_check_gather_scatter(), vect_convert_mask_for_vectype(), vect_get_load_store_mask(), vect_get_store_rhs(), vect_pattern_detected(), and vect_recog_temp_ssa_var().
|
static |
Function vect_recog_gcond_pattern Try to find pattern like following: if (a op b) where operator 'op' is not != and convert it to an adjusted boolean pattern mask = a op b if (mask != 0) and set the mask type on MASK. Input: * STMT_VINFO: The stmt at the end from which the pattern search begins, i.e. cast of a bool to an integer type. Output: * TYPE_OUT: The type of the output of this pattern. * Return value: A new stmt that will be used to replace the pattern.
References append_pattern_def_seq(), boolean_type_node, build_int_cst(), dyn_cast(), get_vectype_for_scalar_type(), gimple_build_assign(), gimple_build_cond(), gimple_cond_code(), gimple_cond_lhs(), gimple_cond_rhs(), LOOP_VINFO_EARLY_BREAKS, NULL, NULL_TREE, STMT_VINFO_STMT, TREE_TYPE, truth_type_for(), vect_pattern_detected(), vect_recog_temp_ssa_var(), VECT_SCALAR_BOOLEAN_TYPE_P, VECTOR_TYPE_P, and zerop().
|
static |
Function vect_recog_mask_conversion_pattern Try to find statements which require boolean type converison. Additional conversion statements are added to handle such cases. For example: bool m_1, m_2, m_3; int i_4, i_5; double d_6, d_7; char c_1, c_2, c_3; S1 m_1 = i_4 > i_5; S2 m_2 = d_6 < d_7; S3 m_3 = m_1 & m_2; S4 c_1 = m_3 ? c_2 : c_3; Will be transformed into: S1 m_1 = i_4 > i_5; S2 m_2 = d_6 < d_7; S3'' m_2' = (_Bool[bitsize=32])m_2 S3' m_3' = m_1 & m_2'; S4'' m_3'' = (_Bool[bitsize=8])m_3' S4' c_1' = m_3'' ? c_2 : c_3;
References vec_info::add_stmt(), append_pattern_def_seq(), build_mask_conversion(), build_nonstandard_integer_type(), COMPARISON_CLASS_P, expand_vec_cond_expr_p(), get_mask_type_for_scalar_type(), get_vectype_for_scalar_type(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs3(), gimple_assign_rhs_code(), gimple_build_assign(), gimple_build_call_internal_vec(), gimple_call_arg(), gimple_call_internal_fn(), gimple_call_internal_p(), gimple_call_lhs(), gimple_call_num_args(), gimple_call_set_lhs(), gimple_call_set_nothrow(), i, integer_type_for_mask(), INTEGRAL_TYPE_P, internal_fn_mask_index(), internal_fn_stored_value_index(), internal_store_fn_p(), is_gimple_assign(), is_gimple_call(), known_eq, known_le, vec_info::move_dr(), NULL, NULL_TREE, STMT_VINFO_DATA_REF, tcc_comparison, TREE_CODE, TREE_CODE_CLASS, TREE_OPERAND, TREE_TYPE, TYPE_PRECISION, TYPE_UNSIGNED, TYPE_VECTOR_SUBPARTS(), vect_constant_def, vect_external_def, vect_is_simple_use(), vect_pattern_detected(), vect_recog_temp_ssa_var(), VECT_SCALAR_BOOLEAN_TYPE_P, and vector_element_bits().
|
static |
Function vect_recog_mixed_size_cond_pattern Try to find the following pattern: type x_t, y_t; TYPE a_T, b_T, c_T; loop: S1 a_T = x_t CMP y_t ? b_T : c_T; where type 'TYPE' is an integral type which has different size from 'type'. b_T and c_T are either constants (and if 'TYPE' is wider than 'type', the constants need to fit into an integer type with the same width as 'type') or results of conversion from 'type'. Input: * STMT_VINFO: The stmt from which the pattern search begins. Output: * TYPE_OUT: The type of the output of this pattern. * Return value: A new stmt that will be used to replace the pattern. Additionally a def_stmt is added. a_it = x_t CMP y_t ? b_it : c_it; a_T = (TYPE) a_it;
References append_pattern_def_seq(), build_nonstandard_integer_type(), COMPARISON_CLASS_P, expand_vec_cond_expr_p(), fold_convert, GET_MODE_BITSIZE(), GET_MODE_UNIT_BITSIZE, get_vectype_for_scalar_type(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs3(), gimple_assign_rhs_code(), gimple_build_assign(), int_fits_type_p(), INTEGRAL_TYPE_P, is_gimple_assign(), NULL, NULL_TREE, SCALAR_INT_TYPE_MODE, SCALAR_TYPE_MODE, STMT_VINFO_DEF_TYPE, TREE_CODE, TREE_OPERAND, TREE_TYPE, type(), type_conversion_p(), TYPE_MODE, TYPE_UNSIGNED, types_compatible_p(), unshare_expr(), vect_internal_def, vect_pattern_detected(), and vect_recog_temp_ssa_var().
|
static |
Detects pattern with a modulo operation (S1) where both arguments are variables of integral type. The statement is replaced by division, multiplication, and subtraction. The last statement (S4) is returned. Example: S1 c_t = a_t % b_t; is replaced by S2 x_t = a_t / b_t; S3 y_t = x_t * b_t; S4 z_t = a_t - y_t;
References append_pattern_def_seq(), get_vectype_for_scalar_type(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_build_assign(), is_gimple_assign(), NULL, r, STMT_VINFO_STMT, target_has_vecop_for_code(), TREE_CODE, TREE_TYPE, vect_pattern_detected(), and vect_recog_temp_ssa_var().
|
static |
Recognize the following patterns: ATYPE a; // narrower than TYPE BTYPE b; // narrower than TYPE 1) Multiply high with scaling TYPE res = ((TYPE) a * (TYPE) b) >> c; Here, c is bitsize (TYPE) / 2 - 1. 2) ... or also with rounding TYPE res = (((TYPE) a * (TYPE) b) >> d + 1) >> 1; Here, d is bitsize (TYPE) / 2 - 2. 3) Normal multiply high TYPE res = ((TYPE) a * (TYPE) b) >> e; Here, e is bitsize (TYPE) / 2. where only the bottom half of res is used.
References build_nonstandard_integer_type(), direct_internal_fn_supported_p(), dump_enabled_p(), dump_printf_loc(), dyn_cast(), get_vectype_for_scalar_type(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_build_call_internal(), gimple_call_set_lhs(), gimple_location(), gimple_set_location(), integer_onep(), INTEGRAL_TYPE_P, MSG_NOTE, NULL, OPTIMIZE_FOR_SPEED, wi::to_widest(), TREE_CODE, TREE_TYPE, TYPE_PRECISION, TYPE_UNSIGNED, vect_convert_inputs(), vect_convert_output(), vect_element_precision(), vect_get_internal_def(), vect_location, vect_look_through_possible_promotion(), vect_pattern_detected(), vect_recog_temp_ssa_var(), and vect_widened_op_tree().
|
static |
Detect multiplication by constant and convert it into a sequence of shifts and additions, subtractions, negations. We reuse the choose_mult_variant algorithms from expmed.cc Input/Output: STMT_VINFO: The stmt from which the pattern search begins, i.e. the mult stmt. Output: * TYPE_OUT: The type of the output of this pattern. * Return value: A new stmt that will be used to replace the multiplication.
References get_vectype_for_scalar_type(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), INTEGRAL_TYPE_P, is_gimple_assign(), NULL, NULL_TREE, optab_default, optab_for_tree_code(), optab_handler(), TREE_CODE, TREE_TYPE, type_has_mode_precision_p(), TYPE_MODE, unknown_optab, vect_pattern_detected(), and vect_synth_mult_by_constant().
|
static |
Recognize cases in which an operation is performed in one type WTYPE but could be done more efficiently in a narrower type NTYPE. For example, if we have: ATYPE a; // narrower than NTYPE BTYPE b; // narrower than NTYPE WTYPE aw = (WTYPE) a; WTYPE bw = (WTYPE) b; WTYPE res = aw + bw; // only uses of aw and bw then it would be more efficient to do: NTYPE an = (NTYPE) a; NTYPE bn = (NTYPE) b; NTYPE resn = an + bn; WTYPE res = (WTYPE) resn; Other situations include things like: ATYPE a; // NTYPE or narrower WTYPE aw = (WTYPE) a; WTYPE res = aw + b; when only "(NTYPE) res" is significant. In that case it's more efficient to truncate "b" and do the operation on NTYPE instead: NTYPE an = (NTYPE) a; NTYPE bn = (NTYPE) b; // truncation NTYPE resn = an + bn; WTYPE res = (WTYPE) resn; All users of "res" should then use "resn" instead, making the final statement dead (not marked as relevant). The final statement is still needed to maintain the type correctness of the IR. vect_determine_precisions has already determined the minimum precison of the operation and the minimum precision required by users of the result.
References build_nonstandard_integer_type(), dump_enabled_p(), dump_printf_loc(), dyn_cast(), get_vectype_for_scalar_type(), gimple_assign_lhs(), gimple_assign_rhs_code(), gimple_build_assign(), gimple_location(), gimple_num_ops(), gimple_op(), gimple_set_location(), i, MAX, MIN, MSG_NOTE, NULL, STMT_VINFO_DEF_TYPE, TREE_CODE, TREE_TYPE, TYPE_OVERFLOW_UNDEFINED, TYPE_PRECISION, UNSIGNED, vect_constant_def, vect_convert_inputs(), vect_convert_output(), vect_element_precision(), vect_internal_def, vect_location, vect_look_through_possible_promotion(), vect_pattern_detected(), vect_recog_temp_ssa_var(), and vect_reduction_def.
|
static |
Function vect_recog_popcount_clz_ctz_ffs_pattern Try to find the following pattern: UTYPE1 A; TYPE1 B; UTYPE2 temp_in; TYPE3 temp_out; temp_in = (UTYPE2)A; temp_out = __builtin_popcount{,l,ll} (temp_in); B = (TYPE1) temp_out; TYPE2 may or may not be equal to TYPE3. i.e. TYPE2 is equal to TYPE3 for __builtin_popcount i.e. TYPE2 is not equal to TYPE3 for __builtin_popcountll Input: * STMT_VINFO: The stmt from which the pattern search begins. here it starts with B = (TYPE1) temp_out; Output: * TYPE_OUT: The vector 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: B = .POPCOUNT (A); Similarly for clz, ctz and ffs.
References vec_info::add_stmt(), append_pattern_def_seq(), build_int_cst(), CLZ_DEFINED_VALUE_AT_ZERO, CONVERT_EXPR_CODE_P, CTZ_DEFINED_VALUE_AT_ZERO, d2, direct_internal_fn_supported_p(), dump_enabled_p(), dump_printf_loc(), dyn_cast(), gcc_assert, gcc_unreachable, get_vectype_for_scalar_type(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs_code(), gimple_build_assign(), gimple_build_call_internal(), gimple_call_arg(), gimple_call_combined_fn(), gimple_call_internal_p(), gimple_call_num_args(), gimple_call_set_lhs(), gimple_location(), gimple_seq_add_seq_without_update(), gimple_set_location(), has_single_use(), integer_type_node, INTEGRAL_TYPE_P, is_gimple_call(), MSG_NOTE, NULL, NULL_TREE, vect_unpromoted_value::op, OPTIMIZE_FOR_SPEED, SCALAR_INT_TYPE_MODE, SSA_NAME_DEF_STMT, STMT_VINFO_PATTERN_DEF_SEQ, STMT_VINFO_VECTYPE, TREE_CODE, tree_to_shwi(), TREE_TYPE, vect_unpromoted_value::type, type_has_mode_precision_p(), TYPE_PRECISION, TYPE_UNSIGNED, vect_location, vect_look_through_possible_promotion(), vect_pattern_detected(), vect_recog_ctz_ffs_pattern(), and vect_recog_temp_ssa_var().
|
static |
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: * STMT_VINFO: The stmt from which the pattern search begins. Output: * 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 * x or x = sqrt (x)
References append_pattern_def_seq(), BUILT_IN_NORMAL, builtin_decl_implicit(), dconst2, dconsthalf, DECL_ATTRIBUTES, DECL_FUNCTION_CODE(), symtab_node::definition, direct_internal_fn_supported_p(), exp(), expand_simd_clones(), fold_const_call(), g, cgraph_node::get_create(), get_vectype_for_scalar_type(), gimple_build_assign(), gimple_build_call(), gimple_build_call_internal(), gimple_call_arg(), gimple_call_builtin_p(), gimple_call_combined_fn(), gimple_call_fndecl(), gimple_call_lhs(), gimple_call_set_lhs(), gimple_call_set_nothrow(), is_gimple_call(), lookup_attribute(), NULL, OPTIMIZE_FOR_SPEED, real_equal(), cgraph_node::simd_clones, targetm, TREE_CODE, tree_fits_shwi_p(), TREE_REAL_CST, tree_to_shwi(), TREE_TYPE, vect_recog_temp_ssa_var(), and vect_supportable_direct_optab_p().
|
static |
Detect a rotate pattern wouldn't be otherwise vectorized: type a_t, b_t, c_t; S0 a_t = b_t r<< c_t; Input/Output: * STMT_VINFO: The stmt from which the pattern search begins, i.e. the shift/rotate stmt. The original stmt (S0) is replaced with a sequence: S1 d_t = -c_t; S2 e_t = d_t & (B - 1); S3 f_t = b_t << c_t; S4 g_t = b_t >> e_t; S0 a_t = f_t | g_t; where B is element bitsize of type. Output: * TYPE_OUT: The type of the output of this pattern. * Return value: A new stmt that will be used to replace the rotate S0 stmt.
References append_pattern_def_seq(), as_a(), build_int_cst(), can_vec_perm_const_p(), char_type_node, gcc_assert, GET_MODE_PRECISION(), get_same_sized_vectype(), get_vectype_for_scalar_type(), gimple_assign_cast_p(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_build_assign(), gimple_build_call(), gimple_call_arg(), gimple_call_builtin_p(), gimple_call_fndecl(), gimple_call_fntype(), gimple_call_lhs(), gimple_call_set_fntype(), gimple_call_set_lhs(), gsi_insert_on_edge_immediate(), i, integer_type_node, integer_zerop(), INTEGRAL_TYPE_P, is_a(), is_gimple_assign(), NULL, NULL_TREE, optab_for_tree_code(), optab_handler(), optab_scalar, optab_vector, SCALAR_INT_TYPE_MODE, TREE_CODE, tree_fits_uhwi_p(), tree_to_uhwi(), TREE_TYPE, type(), TYPE_MODE, TYPE_PRECISION, TYPE_VECTOR_SUBPARTS(), unsigned_type_for(), useless_type_conversion_p(), vect_constant_def, vect_external_def, vect_get_external_def_edge(), vect_internal_def, vect_is_simple_use(), vect_pattern_detected(), and vect_recog_temp_ssa_var().
|
static |
Function vect_recog_sad_pattern Try to find the following Sum of Absolute Difference (SAD) pattern: type x_t, y_t; signed TYPE1 diff, abs_diff; TYPE2 sum = init; loop: sum_0 = phi <init, sum_1> S1 x_t = ... S2 y_t = ... S3 x_T = (TYPE1) x_t; S4 y_T = (TYPE1) y_t; S5 diff = x_T - y_T; S6 abs_diff = ABS_EXPR <diff>; [S7 abs_diff = (TYPE2) abs_diff; #optional] S8 sum_1 = abs_diff + sum_0; where 'TYPE1' is at least double the size of type 'type', and 'TYPE2' is the same size of 'TYPE1' or bigger. This is a special case of a reduction computation. Input: * STMT_VINFO: The stmt from which the pattern search begins. In the example, when this function is called with S8, the pattern {S3,S4,S5,S6,S7,S8} will be detected. Output: * 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: SAD_EXPR <x_t, y_t, sum_0>
References dyn_cast(), gimple_build_assign(), gimple_call_arg(), gimple_call_internal_fn(), gimple_call_internal_p(), gimple_call_num_args(), gimple_get_lhs(), NULL, vect_unpromoted_value::op, TREE_TYPE, vect_unpromoted_value::type, vect_convert_inputs(), vect_get_internal_def(), vect_look_through_possible_promotion(), vect_pattern_detected(), vect_reassociating_reduction_p(), vect_recog_absolute_difference(), vect_recog_temp_ssa_var(), and vect_supportable_direct_optab_p().
|
static |
|
static |
|
static |
References append_pattern_def_seq(), direct_internal_fn_supported_p(), get_vectype_for_scalar_type(), gimple_build_call_internal(), gimple_call_set_lhs(), gimple_call_set_nothrow(), NULL, NULL_TREE, algorithm::ops, OPTIMIZE_FOR_BOTH, TREE_TYPE, vect_unpromoted_value::type, TYPE_PRECISION, types_compatible_p(), vect_look_through_possible_promotion(), and vect_recog_temp_ssa_var().
Referenced by vect_recog_sat_sub_pattern().
|
static |
References direct_internal_fn_supported_p(), get_vectype_for_scalar_type(), gimple_assign_lhs(), gimple_build_call_internal(), gimple_call_set_lhs(), gimple_call_set_nothrow(), gimple_location(), gimple_set_location(), gimple_unsigned_integer_sat_trunc(), is_gimple_assign(), NULL, NULL_TREE, algorithm::ops, OPTIMIZE_FOR_BOTH, STMT_VINFO_STMT, TREE_TYPE, type_has_mode_precision_p(), and vect_recog_temp_ssa_var().
Helper to return a new temporary for pattern of TYPE for STMT. If STMT is NULL, the caller must set SSA_NAME_DEF_STMT for the returned SSA var.
References make_temp_ssa_name().
Referenced by adjust_bool_pattern(), adjust_bool_pattern_cast(), apply_binop_and_append_stmt(), build_mask_conversion(), synth_lshift_by_additions(), vect_add_conversion_to_pattern(), vect_convert_input(), vect_convert_output(), vect_recog_abd_pattern(), vect_recog_average_pattern(), vect_recog_bit_insert_pattern(), vect_recog_bitfield_ref_pattern(), vect_recog_bool_pattern(), vect_recog_build_binary_gimple_stmt(), vect_recog_cast_forwprop_pattern(), vect_recog_cond_expr_convert_pattern(), vect_recog_cond_store_pattern(), vect_recog_ctz_ffs_pattern(), vect_recog_divmod_pattern(), vect_recog_dot_prod_pattern(), vect_recog_gather_scatter_pattern(), vect_recog_gcond_pattern(), vect_recog_mask_conversion_pattern(), vect_recog_mixed_size_cond_pattern(), vect_recog_mod_var_pattern(), vect_recog_mulhs_pattern(), vect_recog_over_widening_pattern(), vect_recog_popcount_clz_ctz_ffs_pattern(), vect_recog_pow_pattern(), vect_recog_rotate_pattern(), vect_recog_sad_pattern(), vect_recog_sat_sub_pattern_transform(), vect_recog_sat_trunc_pattern(), vect_recog_vector_vector_shift_pattern(), vect_recog_widen_abd_pattern(), vect_recog_widen_op_pattern(), vect_recog_widen_sum_pattern(), vect_split_statement(), and vect_synth_mult_by_constant().
|
static |
Detect a vector by vector shift pattern that wouldn't be otherwise vectorized: type a_t; TYPE b_T, res_T; S1 a_t = ; S2 b_T = ; S3 res_T = b_T op a_t; where type 'TYPE' is a type with different size than 'type', and op is <<, >> or rotate. Also detect cases: type a_t; TYPE b_T, c_T, res_T; S0 c_T = ; S1 a_t = (type) c_T; S2 b_T = ; S3 res_T = b_T op a_t; Input/Output: * STMT_VINFO: The stmt from which the pattern search begins, i.e. the shift/rotate stmt. The original stmt (S3) is replaced with a shift/rotate which has same type on both operands, in the second case just b_T op c_T, in the first case with added cast from a_t to c_T in STMT_VINFO_PATTERN_DEF_SEQ. Output: * TYPE_OUT: The type of the output of this pattern. * Return value: A new stmt that will be used to replace the shift/rotate S3 stmt.
References append_pattern_def_seq(), build_low_bits_mask(), dyn_cast(), get_vectype_for_scalar_type(), gimple_assign_cast_p(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_build_assign(), INTEGRAL_TYPE_P, is_gimple_assign(), NULL, NULL_TREE, TREE_CODE, TREE_TYPE, type_has_mode_precision_p(), TYPE_MODE, TYPE_PRECISION, vect_get_internal_def(), vect_pattern_detected(), and vect_recog_temp_ssa_var().
|
static |
Try to detect abd on widened inputs, converting IFN_ABD to IFN_VEC_WIDEN_ABD.
References CONVERT_EXPR_CODE_P, dyn_cast(), get_vectype_for_scalar_type(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs_code(), gimple_build_call_internal(), gimple_call_arg(), gimple_call_internal_fn(), gimple_call_internal_p(), gimple_call_set_lhs(), gimple_location(), gimple_set_location(), INTEGRAL_TYPE_P, NULL, STMT_VINFO_STMT, supportable_widening_operation(), TREE_TYPE, TYPE_PRECISION, TYPE_UNSIGNED, vect_get_internal_def(), vect_look_through_possible_promotion(), vect_pattern_detected(), and vect_recog_temp_ssa_var().
|
static |
Try to detect subtraction on widened inputs, converting MINUS_EXPR to IFN_VEC_WIDEN_MINUS. See vect_recog_widen_op_pattern for details.
References vect_recog_widen_op_pattern().
|
static |
Try to detect multiplication on widened inputs, converting MULT_EXPR to WIDEN_MULT_EXPR. See vect_recog_widen_op_pattern for details.
References vect_recog_widen_op_pattern().
|
static |
Recognize an operation that performs ORIG_CODE on widened inputs, so that it can be treated as though it had the form: A_TYPE a; B_TYPE b; HALF_TYPE a_cast = (HALF_TYPE) a; // possible no-op HALF_TYPE b_cast = (HALF_TYPE) b; // possible no-op | RES_TYPE a_extend = (RES_TYPE) a_cast; // promotion from HALF_TYPE | RES_TYPE b_extend = (RES_TYPE) b_cast; // promotion from HALF_TYPE | RES_TYPE res = a_extend ORIG_CODE b_extend; Try to replace the pattern with: A_TYPE a; B_TYPE b; HALF_TYPE a_cast = (HALF_TYPE) a; // possible no-op HALF_TYPE b_cast = (HALF_TYPE) b; // possible no-op | EXT_TYPE ext = a_cast WIDE_CODE b_cast; | RES_TYPE res = (EXT_TYPE) ext; // possible no-op where EXT_TYPE is wider than HALF_TYPE but has the same signedness. SHIFT_P is true if ORIG_CODE and WIDE_CODE are shifts. NAME is the name of the pattern being matched, for dump purposes.
References build_nonstandard_integer_type(), get_vectype_for_scalar_type(), gimple_get_lhs(), NULL, supportable_widening_operation(), TREE_TYPE, type(), TYPE_PRECISION, TYPE_UNSIGNED, vect_convert_inputs(), vect_convert_output(), vect_gimple_build(), vect_pattern_detected(), vect_recog_temp_ssa_var(), and vect_widened_op_tree().
Referenced by vect_recog_widen_minus_pattern(), vect_recog_widen_mult_pattern(), vect_recog_widen_plus_pattern(), and vect_recog_widen_shift_pattern().
|
static |
Try to detect addition on widened inputs, converting PLUS_EXPR to IFN_VEC_WIDEN_PLUS. See vect_recog_widen_op_pattern for details.
References vect_recog_widen_op_pattern().
|
static |
Try to detect a shift left of a widened input, converting LSHIFT_EXPR to WIDEN_LSHIFT_EXPR. See vect_recog_widen_op_pattern for details.
References vect_recog_widen_op_pattern().
|
static |
Function vect_recog_widen_sum_pattern Try to find the following pattern: type x_t; TYPE x_T, sum = init; loop: sum_0 = phi <init, sum_1> S1 x_t = *p; S2 x_T = (TYPE) x_t; S3 sum_1 = x_T + sum_0; where type 'TYPE' is at least double the size of type 'type', i.e - we're summing elements of type 'type' into an accumulator of type 'TYPE'. This is a special case of a reduction computation. Input: * STMT_VINFO: The stmt from which the pattern search begins. In the example, when this function is called with S3, the pattern {S2,S3} will be detected. Output: * 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: WIDEN_SUM <x_t, sum_0> Note: The widening-sum idiom is a widening reduction pattern that is vectorized without preserving all the intermediate results. It produces only N/2 (widened) results (by summing up pairs of intermediate results) rather than all N results. Therefore, we cannot allow this pattern when we want to get all the results and in the correct order (as is the case when this computation is in an inner-loop nested in an outer-loop that us being vectorized).
References gimple_build_assign(), gimple_get_lhs(), vec_info::lookup_def(), NULL, vect_unpromoted_value::op, TREE_CODE, TREE_TYPE, type(), vect_unpromoted_value::type, TYPE_PRECISION, vect_look_through_possible_promotion(), vect_pattern_detected(), vect_reassociating_reduction_p(), vect_recog_temp_ssa_var(), and vect_supportable_direct_optab_p().
|
static |
Record that STMT_INFO only requires MIN_INPUT_PRECISION from its non-boolean inputs, all of which have type TYPE. MIN_INPUT_PRECISION is an arbitrary bit precision; it might not be a whole number of bytes.
References MAX, and TYPE_PRECISION.
Referenced by vect_determine_precisions_from_range(), and vect_determine_precisions_from_users().
|
static |
Record that STMT_INFO could be changed from operating on TYPE to operating on a type with the precision and sign given by PRECISION and SIGN respectively. PRECISION is an arbitrary bit precision; it might not be a whole number of bytes.
References TYPE_PRECISION, and vect_element_precision().
Referenced by vect_determine_precisions_from_range(), and vect_determine_precisions_from_users().
|
static |
Set the pattern statement of ORIG_STMT_INFO to PATTERN_STMT. Also set the vector type of PATTERN_STMT to VECTYPE, if it doesn't have one already.
References STMT_VINFO_IN_PATTERN_P, STMT_VINFO_RELATED_STMT, and vect_init_pattern_stmt().
Referenced by vect_mark_pattern_stmts(), and vect_split_statement().
|
static |
STMT2_INFO describes a type conversion that could be split into STMT1 followed by a version of STMT2_INFO that takes NEW_RHS as its first input. Try to do this using pattern statements, returning true on success.
References dump_enabled_p(), dump_printf_loc(), gcc_assert, get_vectype_for_scalar_type(), gimple_assign_set_rhs1(), gimple_build_assign(), gimple_get_lhs(), gimple_seq_add_stmt_without_update(), gsi_for_stmt(), gsi_insert_before_without_update(), GSI_SAME_STMT, is_pattern_stmt_p(), MSG_NOTE, NULL, STMT_VINFO_PATTERN_DEF_SEQ, STMT_VINFO_RELATED_STMT, TREE_TYPE, vect_init_pattern_stmt(), vect_location, vect_recog_temp_ssa_var(), and vect_set_pattern_stmt().
Referenced by vect_convert_input().
|
static |
Return true if the target supports a vector version of CODE, where CODE is known to map to a conversion optab with the given SUBTYPE. ITYPE specifies the type of (some of) the scalar inputs and OTYPE specifies the type of the scalar result. When returning true, set *VECOTYPE_OUT to the vector version of OTYPE. Also set *VECITYPE_OUT to the vector version of ITYPE if VECITYPE_OUT is nonnull.
References directly_supported_p(), and get_vectype_for_scalar_type().
Referenced by vect_recog_dot_prod_pattern().
|
static |
Return true if the target supports a vector version of CODE, where CODE is known to map to a direct optab with the given SUBTYPE. ITYPE specifies the type of (some of) the scalar inputs and OTYPE specifies the type of the scalar result. If CODE allows the inputs and outputs to have different type (such as for WIDEN_SUM_EXPR), it is the input mode rather than the output mode that determines the appropriate target pattern. Operand 0 of the target pattern then specifies the mode that the output must have. When returning true, set *VECOTYPE_OUT to the vector version of OTYPE. Also set *VECITYPE_OUT to the vector version of ITYPE if VECITYPE_OUT is nonnull.
References get_vectype_for_scalar_type(), insn_data, optab_for_tree_code(), optab_handler(), and TYPE_MODE.
Referenced by vect_recog_pow_pattern(), vect_recog_sad_pattern(), and vect_recog_widen_sum_pattern().
|
static |
Synthesize a multiplication of OP by an INTEGER_CST VAL using shifts and simple arithmetic operations to be vectorized. Record the statements produced in STMT_VINFO and return the last statement in the sequence or NULL if it's not possible to synthesize such a multiplication. This function mirrors the behavior of expand_mult_const in expmed.cc but works on tree-ssa form.
References add_variant, alg_add_factor, alg_add_t2_m, alg_add_t_m2, alg_shift, alg_sub_factor, alg_sub_t2_m, alg_sub_t_m2, alg_zero, append_pattern_def_seq(), apply_binop_and_append_stmt(), build_int_cst(), choose_mult_variant(), gcc_unreachable, get_vectype_for_scalar_type(), gimple_build_assign(), i, integer_zerop(), algorithm::log, MAX_COST, negate_variant, NULL, NULL_TREE, algorithm::op, algorithm::ops, synth_lshift_by_additions(), target_supports_mult_synth_alg(), tree_fits_shwi_p(), tree_to_shwi(), TREE_TYPE, TYPE_MODE, TYPE_OVERFLOW_WRAPS, unsigned_type_for(), vect_recog_temp_ssa_var(), vect_supportable_shift(), and VECTOR_MODE_P.
Referenced by vect_recog_mult_pattern().
Return true if the operation given by CODE can be truncated to N bits when only N bits of the output are needed. This is only true if bit N+1 of the inputs has no effect on the low N bits of the result.
Referenced by vect_determine_precisions_from_range(), and vect_determine_precisions_from_users().
|
static |
Check whether STMT_INFO can be viewed as a tree of integer operations in which each node either performs CODE or WIDENED_CODE, and where each leaf operand is narrower than the result of STMT_INFO. MAX_NOPS specifies the maximum number of leaf operands. SHIFT_P says whether CODE and WIDENED_CODE are some sort of shift. If STMT_INFO is such a tree, return the number of leaf operands and describe them in UNPROM[0] onwards. Also set *COMMON_TYPE to a type that (a) is narrower than the result of STMT_INFO and (b) can hold all leaf operand values. If SUBTYPE then allow that the signs of the operands may differ in signs but not in precision. SUBTYPE is updated to reflect this. Return 0 if STMT_INFO isn't such a tree, or if no such COMMON_TYPE exists.
References vect_unpromoted_value::dt, gimple_arg(), gimple_assign_rhs_code(), gimple_call_combined_fn(), gimple_get_lhs(), i, INTEGRAL_TYPE_P, is_gimple_assign(), is_gimple_call(), NULL, vect_unpromoted_value::op, optab_vector_mixed_sign, vect_unpromoted_value::set_op(), TREE_CODE, TREE_TYPE, vect_unpromoted_value::type, TYPE_PRECISION, vect_constant_def, vect_get_internal_def(), vect_internal_def, vect_is_simple_use(), vect_joust_widened_integer(), vect_joust_widened_type(), vect_look_through_possible_promotion(), and vect_widened_op_tree().
Referenced by vect_recog_absolute_difference(), vect_recog_average_pattern(), vect_recog_dot_prod_pattern(), vect_recog_mulhs_pattern(), vect_recog_widen_op_pattern(), and vect_widened_op_tree().
|
static |
Note that ordering matters - the first pattern matching on a stmt is taken which means usually the more complex one needs to preceed the less comples onex (widen_sum only after dot_prod or sad for example).
Referenced by vect_pattern_recog().