GCC Middle and Back End API Reference
tree-vect-patterns.cc File 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"
Include dependency graph for tree-vect-patterns.cc:

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 *)
 

Functions

bool vect_get_range_info (tree var, wide_int *min_value, wide_int *max_value)
 
static void vect_pattern_detected (const char *name, gimple *stmt)
 
static stmt_vec_info vect_init_pattern_stmt (vec_info *vinfo, gimple *pattern_stmt, stmt_vec_info orig_stmt_info, tree vectype)
 
static void vect_set_pattern_stmt (vec_info *vinfo, gimple *pattern_stmt, stmt_vec_info orig_stmt_info, tree vectype)
 
static void append_pattern_def_seq (vec_info *vinfo, stmt_vec_info stmt_info, gimple *new_stmt, tree vectype=NULL_TREE, tree scalar_type_for_mask=NULL_TREE)
 
static void append_inv_pattern_def_seq (vec_info *vinfo, gimple *new_stmt)
 
static edge vect_get_external_def_edge (vec_info *vinfo, tree var)
 
static bool vect_supportable_direct_optab_p (vec_info *vinfo, tree otype, tree_code code, tree itype, tree *vecotype_out, tree *vecitype_out=NULL, enum optab_subtype subtype=optab_default)
 
static bool vect_supportable_conv_optab_p (vec_info *vinfo, tree otype, tree_code code, tree itype, tree *vecotype_out, tree *vecitype_out=NULL, enum optab_subtype subtype=optab_default)
 
static unsigned int vect_element_precision (unsigned int precision)
 
static stmt_vec_info vect_get_internal_def (vec_info *vinfo, tree op)
 
static bool type_conversion_p (vec_info *vinfo, tree name, bool check_sign, tree *orig_type, gimple **def_stmt, bool *promotion)
 
static tree vect_look_through_possible_promotion (vec_info *vinfo, tree op, vect_unpromoted_value *unprom, bool *single_use_p=NULL)
 
static bool vect_joust_widened_integer (tree type, bool shift_p, tree op, tree *common_type)
 
static bool vect_joust_widened_type (tree type, tree new_type, tree *common_type)
 
static unsigned int vect_widened_op_tree (vec_info *vinfo, stmt_vec_info stmt_info, tree_code code, code_helper widened_code, bool shift_p, unsigned int max_nops, vect_unpromoted_value *unprom, tree *common_type, enum optab_subtype *subtype=NULL)
 
static tree vect_recog_temp_ssa_var (tree type, gimple *stmt=NULL)
 
static bool vect_split_statement (vec_info *vinfo, stmt_vec_info stmt2_info, tree new_rhs, gimple *stmt1, tree vectype)
 
static bool vect_recog_absolute_difference (vec_info *vinfo, gassign *abs_stmt, tree *half_type, vect_unpromoted_value unprom[2], gassign **diff_stmt)
 
static tree vect_convert_input (vec_info *vinfo, stmt_vec_info stmt_info, tree type, vect_unpromoted_value *unprom, tree vectype, enum optab_subtype subtype=optab_default)
 
static void vect_convert_inputs (vec_info *vinfo, stmt_vec_info stmt_info, unsigned int n, tree *result, tree type, vect_unpromoted_value *unprom, tree vectype, enum optab_subtype subtype=optab_default)
 
static gimplevect_convert_output (vec_info *vinfo, stmt_vec_info stmt_info, tree type, gimple *pattern_stmt, tree vecitype)
 
static bool vect_reassociating_reduction_p (vec_info *vinfo, stmt_vec_info stmt_info, tree_code code, tree *op0_out, tree *op1_out)
 
bool gimple_cond_expr_convert_p (tree, tree *, tree(*)(tree))
 
static gimplevect_recog_cond_expr_convert_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo, tree *type_out)
 
static gimplevect_recog_dot_prod_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo, tree *type_out)
 
static gimplevect_recog_sad_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo, tree *type_out)
 
static gimplevect_recog_abd_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo, tree *type_out)
 
static gimplevect_recog_widen_op_pattern (vec_info *vinfo, stmt_vec_info last_stmt_info, tree *type_out, tree_code orig_code, code_helper wide_code, bool shift_p, const char *name)
 
static gimplevect_recog_widen_mult_pattern (vec_info *vinfo, stmt_vec_info last_stmt_info, tree *type_out)
 
static gimplevect_recog_widen_plus_pattern (vec_info *vinfo, stmt_vec_info last_stmt_info, tree *type_out)
 
static gimplevect_recog_widen_minus_pattern (vec_info *vinfo, stmt_vec_info last_stmt_info, tree *type_out)
 
static gimplevect_recog_widen_abd_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo, tree *type_out)
 
static gimplevect_recog_ctz_ffs_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo, tree *type_out)
 
static gimplevect_recog_popcount_clz_ctz_ffs_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo, tree *type_out)
 
static gimplevect_recog_pow_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo, tree *type_out)
 
static gimplevect_recog_widen_sum_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo, tree *type_out)
 
static gimplevect_recog_bitfield_ref_pattern (vec_info *vinfo, stmt_vec_info stmt_info, tree *type_out)
 
static gimplevect_recog_bit_insert_pattern (vec_info *vinfo, stmt_vec_info stmt_info, tree *type_out)
 
static gimplevect_recog_over_widening_pattern (vec_info *vinfo, stmt_vec_info last_stmt_info, tree *type_out)
 
static gimplevect_recog_mulhs_pattern (vec_info *vinfo, stmt_vec_info last_stmt_info, tree *type_out)
 
static gimplevect_recog_average_pattern (vec_info *vinfo, stmt_vec_info last_stmt_info, tree *type_out)
 
static gimplevect_recog_cast_forwprop_pattern (vec_info *vinfo, stmt_vec_info last_stmt_info, tree *type_out)
 
static gimplevect_recog_widen_shift_pattern (vec_info *vinfo, stmt_vec_info last_stmt_info, tree *type_out)
 
static gimplevect_recog_rotate_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo, tree *type_out)
 
static gimplevect_recog_vector_vector_shift_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo, tree *type_out)
 
static bool target_has_vecop_for_code (tree_code code, tree vectype)
 
static bool target_supports_mult_synth_alg (struct algorithm *alg, mult_variant var, tree vectype, bool synth_shift_p)
 
static gimplesynth_lshift_by_additions (vec_info *vinfo, tree dest, tree op, HOST_WIDE_INT amnt, stmt_vec_info stmt_info)
 
static tree apply_binop_and_append_stmt (vec_info *vinfo, tree_code code, tree op1, tree op2, stmt_vec_info stmt_vinfo, bool synth_shift_p)
 
static gimplevect_synth_mult_by_constant (vec_info *vinfo, tree op, tree val, stmt_vec_info stmt_vinfo)
 
static gimplevect_recog_mult_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo, tree *type_out)
 
bool gimple_unsigned_integer_sat_add (tree, tree *, tree(*)(tree))
 
bool gimple_unsigned_integer_sat_sub (tree, tree *, tree(*)(tree))
 
bool gimple_unsigned_integer_sat_trunc (tree, tree *, tree(*)(tree))
 
bool gimple_signed_integer_sat_add (tree, tree *, tree(*)(tree))
 
static gimplevect_recog_build_binary_gimple_stmt (vec_info *vinfo, stmt_vec_info stmt_info, internal_fn fn, tree *type_out, tree lhs, tree op_0, tree op_1)
 
static gimplevect_recog_sat_add_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo, tree *type_out)
 
static void vect_recog_sat_sub_pattern_transform (vec_info *vinfo, stmt_vec_info stmt_vinfo, tree lhs, tree *ops)
 
static gimplevect_recog_sat_sub_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo, tree *type_out)
 
static gimplevect_recog_sat_trunc_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo, tree *type_out)
 
static gimplevect_recog_divmod_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo, tree *type_out)
 
static gimplevect_recog_mod_var_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo, tree *type_out)
 
static gimplevect_recog_mixed_size_cond_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo, tree *type_out)
 
static bool check_bool_pattern (tree var, vec_info *vinfo, hash_set< gimple * > &stmts)
 
static tree adjust_bool_pattern_cast (vec_info *vinfo, tree type, tree var, stmt_vec_info stmt_info)
 
static void adjust_bool_pattern (vec_info *vinfo, tree var, tree out_type, stmt_vec_info stmt_info, hash_map< tree, tree > &defs)
 
static int sort_after_uid (const void *p1, const void *p2)
 
static tree adjust_bool_stmts (vec_info *vinfo, hash_set< gimple * > &bool_stmt_set, tree out_type, stmt_vec_info stmt_info)
 
static tree integer_type_for_mask (tree var, vec_info *vinfo)
 
static gimplevect_recog_gcond_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo, tree *type_out)
 
static gimplevect_recog_bool_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo, tree *type_out)
 
static tree build_mask_conversion (vec_info *vinfo, tree mask, tree vectype, stmt_vec_info stmt_vinfo)
 
static gimplevect_recog_mask_conversion_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo, tree *type_out)
 
static tree vect_get_load_store_mask (stmt_vec_info stmt_info)
 
static tree vect_convert_mask_for_vectype (tree mask, tree vectype, stmt_vec_info stmt_info, vec_info *vinfo)
 
static tree vect_add_conversion_to_pattern (vec_info *vinfo, tree type, tree value, stmt_vec_info stmt_info)
 
static gimplevect_recog_gather_scatter_pattern (vec_info *vinfo, stmt_vec_info stmt_info, tree *type_out)
 
static bool vect_cond_store_pattern_same_ref (vec_info *vinfo, stmt_vec_info store_vinfo, tree cond_arg)
 
static gimplevect_recog_cond_store_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo, tree *type_out)
 
static bool vect_narrowable_type_p (tree type)
 
static bool vect_truncatable_operation_p (tree_code code)
 
static void vect_set_operation_type (stmt_vec_info stmt_info, tree type, unsigned int precision, signop sign)
 
static void vect_set_min_input_precision (stmt_vec_info stmt_info, tree type, unsigned int min_input_precision)
 
static bool vect_determine_min_output_precision_1 (vec_info *vinfo, stmt_vec_info stmt_info, tree lhs)
 
static void vect_determine_min_output_precision (vec_info *vinfo, stmt_vec_info stmt_info)
 
static void vect_determine_precisions_from_range (stmt_vec_info stmt_info, gassign *stmt)
 
static void vect_determine_precisions_from_users (stmt_vec_info stmt_info, gassign *stmt)
 
static bool possible_vector_mask_operation_p (stmt_vec_info stmt_info)
 
static void vect_determine_mask_precision (vec_info *vinfo, stmt_vec_info stmt_info)
 
void vect_determine_stmt_precisions (vec_info *vinfo, stmt_vec_info stmt_info)
 
void vect_determine_precisions (vec_info *vinfo)
 
void vect_mark_pattern_stmts (vec_info *vinfo, stmt_vec_info orig_stmt_info, gimple *pattern_stmt, tree pattern_vectype)
 
static void vect_pattern_recog_1 (vec_info *vinfo, const vect_recog_func &recog_func, stmt_vec_info stmt_info)
 
void vect_pattern_recog (vec_info *vinfo)
 
gimplevect_gimple_build (tree lhs, code_helper ch, tree op0, tree op1)
 

Variables

static vect_recog_func vect_vect_recog_func_ptrs []
 

Macro Definition Documentation

◆ INCLUDE_MEMORY

#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 Documentation

◆ vect_recog_func_ptr

typedef gimple *(* vect_recog_func_ptr) (vec_info *, stmt_vec_info, tree *)

Function Documentation

◆ adjust_bool_pattern()

static void adjust_bool_pattern ( vec_info * vinfo,
tree var,
tree out_type,
stmt_vec_info stmt_info,
hash_map< tree, tree > & defs )
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().

◆ adjust_bool_pattern_cast()

static tree adjust_bool_pattern_cast ( vec_info * vinfo,
tree type,
tree var,
stmt_vec_info stmt_info )
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().

◆ adjust_bool_stmts()

static tree adjust_bool_stmts ( vec_info * vinfo,
hash_set< gimple * > & bool_stmt_set,
tree out_type,
stmt_vec_info stmt_info )
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().

◆ append_inv_pattern_def_seq()

static void append_inv_pattern_def_seq ( vec_info * vinfo,
gimple * new_stmt )
inlinestatic
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().

◆ append_pattern_def_seq()

static void append_pattern_def_seq ( vec_info * vinfo,
stmt_vec_info stmt_info,
gimple * new_stmt,
tree vectype = NULL_TREE,
tree scalar_type_for_mask = NULL_TREE )
inlinestatic

◆ apply_binop_and_append_stmt()

static tree apply_binop_and_append_stmt ( vec_info * vinfo,
tree_code code,
tree op1,
tree op2,
stmt_vec_info stmt_vinfo,
bool synth_shift_p )
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().

◆ build_mask_conversion()

static tree build_mask_conversion ( vec_info * vinfo,
tree mask,
tree vectype,
stmt_vec_info stmt_vinfo )
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().

◆ check_bool_pattern()

static bool check_bool_pattern ( tree var,
vec_info * vinfo,
hash_set< gimple * > & stmts )
static
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().

◆ gimple_cond_expr_convert_p()

bool gimple_cond_expr_convert_p ( tree ,
tree * ,
tree(*  )(tree) )
extern
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().

◆ gimple_signed_integer_sat_add()

bool gimple_signed_integer_sat_add ( tree ,
tree * ,
tree(*  )(tree) )
extern

◆ gimple_unsigned_integer_sat_add()

bool gimple_unsigned_integer_sat_add ( tree ,
tree * ,
tree(*  )(tree) )
extern

◆ gimple_unsigned_integer_sat_sub()

bool gimple_unsigned_integer_sat_sub ( tree ,
tree * ,
tree(*  )(tree) )
extern

◆ gimple_unsigned_integer_sat_trunc()

bool gimple_unsigned_integer_sat_trunc ( tree ,
tree * ,
tree(*  )(tree) )
extern

◆ integer_type_for_mask()

static tree integer_type_for_mask ( tree var,
vec_info * vinfo )
static
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().

◆ possible_vector_mask_operation_p()

static bool possible_vector_mask_operation_p ( stmt_vec_info stmt_info)
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().

◆ sort_after_uid()

static int sort_after_uid ( const void * p1,
const void * p2 )
static
Comparison function to qsort a vector of gimple stmts after UID.   

References gimple_uid().

Referenced by adjust_bool_stmts().

◆ synth_lshift_by_additions()

static gimple * synth_lshift_by_additions ( vec_info * vinfo,
tree dest,
tree op,
HOST_WIDE_INT amnt,
stmt_vec_info stmt_info )
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().

◆ target_has_vecop_for_code()

static bool target_has_vecop_for_code ( tree_code code,
tree vectype )
static
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().

◆ target_supports_mult_synth_alg()

static bool target_supports_mult_synth_alg ( struct algorithm * alg,
mult_variant var,
tree vectype,
bool synth_shift_p )
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().

◆ type_conversion_p()

static bool type_conversion_p ( vec_info * vinfo,
tree name,
bool check_sign,
tree * orig_type,
gimple ** def_stmt,
bool * promotion )
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().

◆ vect_add_conversion_to_pattern()

static tree vect_add_conversion_to_pattern ( vec_info * vinfo,
tree type,
tree value,
stmt_vec_info stmt_info )
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().

◆ vect_cond_store_pattern_same_ref()

static bool vect_cond_store_pattern_same_ref ( vec_info * vinfo,
stmt_vec_info store_vinfo,
tree cond_arg )
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().

◆ vect_convert_input()

static tree vect_convert_input ( vec_info * vinfo,
stmt_vec_info stmt_info,
tree type,
vect_unpromoted_value * unprom,
tree vectype,
enum optab_subtype subtype = optab_default )
static

◆ vect_convert_inputs()

static void vect_convert_inputs ( vec_info * vinfo,
stmt_vec_info stmt_info,
unsigned int n,
tree * result,
tree type,
vect_unpromoted_value * unprom,
tree vectype,
enum optab_subtype subtype = optab_default )
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().

◆ vect_convert_mask_for_vectype()

static tree vect_convert_mask_for_vectype ( tree mask,
tree vectype,
stmt_vec_info stmt_info,
vec_info * vinfo )
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().

◆ vect_convert_output()

static gimple * vect_convert_output ( vec_info * vinfo,
stmt_vec_info stmt_info,
tree type,
gimple * pattern_stmt,
tree vecitype )
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().

◆ vect_determine_mask_precision()

◆ vect_determine_min_output_precision()

static void vect_determine_min_output_precision ( vec_info * vinfo,
stmt_vec_info stmt_info )
static

◆ vect_determine_min_output_precision_1()

static bool vect_determine_min_output_precision_1 ( vec_info * vinfo,
stmt_vec_info stmt_info,
tree lhs )
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().

◆ vect_determine_precisions()

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().

◆ vect_determine_precisions_from_range()

static void vect_determine_precisions_from_range ( stmt_vec_info stmt_info,
gassign * stmt )
static

◆ vect_determine_precisions_from_users()

static void vect_determine_precisions_from_users ( stmt_vec_info stmt_info,
gassign * stmt )
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().

◆ 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().

◆ vect_element_precision()

static unsigned int vect_element_precision ( unsigned int precision)
static

◆ vect_get_external_def_edge()

static edge vect_get_external_def_edge ( vec_info * vinfo,
tree var )
static
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().

◆ vect_get_internal_def()

static stmt_vec_info vect_get_internal_def ( vec_info * vinfo,
tree op )
static

◆ vect_get_load_store_mask()

static tree vect_get_load_store_mask ( stmt_vec_info stmt_info)
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().

◆ vect_get_range_info()

bool vect_get_range_info ( tree var,
wide_int * min_value,
wide_int * max_value )
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().

◆ vect_gimple_build()

◆ vect_init_pattern_stmt()

static stmt_vec_info vect_init_pattern_stmt ( vec_info * vinfo,
gimple * pattern_stmt,
stmt_vec_info orig_stmt_info,
tree vectype )
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().

◆ vect_joust_widened_integer()

static bool vect_joust_widened_integer ( tree type,
bool shift_p,
tree op,
tree * common_type )
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().

◆ vect_joust_widened_type()

static bool vect_joust_widened_type ( tree type,
tree new_type,
tree * common_type )
static
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().

◆ vect_look_through_possible_promotion()

static tree vect_look_through_possible_promotion ( vec_info * vinfo,
tree op,
vect_unpromoted_value * unprom,
bool * single_use_p = NULL )
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().

◆ vect_mark_pattern_stmts()

◆ vect_narrowable_type_p()

static bool vect_narrowable_type_p ( tree type)
static
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().

◆ vect_pattern_detected()

◆ vect_pattern_recog()

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().

◆ vect_pattern_recog_1()

static void vect_pattern_recog_1 ( vec_info * vinfo,
const vect_recog_func & recog_func,
stmt_vec_info stmt_info )
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().

◆ vect_reassociating_reduction_p()

static bool vect_reassociating_reduction_p ( vec_info * vinfo,
stmt_vec_info stmt_info,
tree_code code,
tree * op0_out,
tree * op1_out )
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().

◆ vect_recog_abd_pattern()

static gimple * vect_recog_abd_pattern ( vec_info * vinfo,
stmt_vec_info stmt_vinfo,
tree * type_out )
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().

◆ vect_recog_absolute_difference()

static bool vect_recog_absolute_difference ( vec_info * vinfo,
gassign * abs_stmt,
tree * half_type,
vect_unpromoted_value unprom[2],
gassign ** diff_stmt )
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().

◆ vect_recog_average_pattern()

static gimple * vect_recog_average_pattern ( vec_info * vinfo,
stmt_vec_info last_stmt_info,
tree * type_out )
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().

◆ vect_recog_bit_insert_pattern()

static gimple * vect_recog_bit_insert_pattern ( vec_info * vinfo,
stmt_vec_info stmt_info,
tree * type_out )
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().

◆ vect_recog_bitfield_ref_pattern()

static gimple * vect_recog_bitfield_ref_pattern ( vec_info * vinfo,
stmt_vec_info stmt_info,
tree * type_out )
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().

◆ vect_recog_bool_pattern()

static gimple * vect_recog_bool_pattern ( vec_info * vinfo,
stmt_vec_info stmt_vinfo,
tree * type_out )
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.

◆ vect_recog_build_binary_gimple_stmt()

◆ vect_recog_cast_forwprop_pattern()

static gimple * vect_recog_cast_forwprop_pattern ( vec_info * vinfo,
stmt_vec_info last_stmt_info,
tree * type_out )
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.

◆ vect_recog_cond_expr_convert_pattern()

static gimple * vect_recog_cond_expr_convert_pattern ( vec_info * vinfo,
stmt_vec_info stmt_vinfo,
tree * type_out )
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().

◆ vect_recog_cond_store_pattern()

static gimple * vect_recog_cond_store_pattern ( vec_info * vinfo,
stmt_vec_info stmt_vinfo,
tree * type_out )
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.

◆ vect_recog_ctz_ffs_pattern()

static gimple * vect_recog_ctz_ffs_pattern ( vec_info * vinfo,
stmt_vec_info stmt_vinfo,
tree * type_out )
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().

◆ vect_recog_divmod_pattern()

static gimple * vect_recog_divmod_pattern ( vec_info * vinfo,
stmt_vec_info stmt_vinfo,
tree * type_out )
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().

◆ vect_recog_dot_prod_pattern()

static gimple * vect_recog_dot_prod_pattern ( vec_info * vinfo,
stmt_vec_info stmt_vinfo,
tree * type_out )
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().

◆ vect_recog_gather_scatter_pattern()

static gimple * vect_recog_gather_scatter_pattern ( vec_info * vinfo,
stmt_vec_info stmt_info,
tree * type_out )
static

◆ vect_recog_gcond_pattern()

static gimple * vect_recog_gcond_pattern ( vec_info * vinfo,
stmt_vec_info stmt_vinfo,
tree * type_out )
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().

◆ vect_recog_mask_conversion_pattern()

static gimple * vect_recog_mask_conversion_pattern ( vec_info * vinfo,
stmt_vec_info stmt_vinfo,
tree * type_out )
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().

◆ vect_recog_mixed_size_cond_pattern()

static gimple * vect_recog_mixed_size_cond_pattern ( vec_info * vinfo,
stmt_vec_info stmt_vinfo,
tree * type_out )
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().

◆ vect_recog_mod_var_pattern()

static gimple * vect_recog_mod_var_pattern ( vec_info * vinfo,
stmt_vec_info stmt_vinfo,
tree * type_out )
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().

◆ vect_recog_mulhs_pattern()

static gimple * vect_recog_mulhs_pattern ( vec_info * vinfo,
stmt_vec_info last_stmt_info,
tree * type_out )
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().

◆ vect_recog_mult_pattern()

static gimple * vect_recog_mult_pattern ( vec_info * vinfo,
stmt_vec_info stmt_vinfo,
tree * type_out )
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().

◆ vect_recog_over_widening_pattern()

static gimple * vect_recog_over_widening_pattern ( vec_info * vinfo,
stmt_vec_info last_stmt_info,
tree * type_out )
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.

◆ vect_recog_popcount_clz_ctz_ffs_pattern()

static gimple * vect_recog_popcount_clz_ctz_ffs_pattern ( vec_info * vinfo,
stmt_vec_info stmt_vinfo,
tree * type_out )
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().

◆ vect_recog_pow_pattern()

static gimple * vect_recog_pow_pattern ( vec_info * vinfo,
stmt_vec_info stmt_vinfo,
tree * type_out )
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().

◆ vect_recog_rotate_pattern()

static gimple * vect_recog_rotate_pattern ( vec_info * vinfo,
stmt_vec_info stmt_vinfo,
tree * type_out )
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().

◆ vect_recog_sad_pattern()

static gimple * vect_recog_sad_pattern ( vec_info * vinfo,
stmt_vec_info stmt_vinfo,
tree * type_out )
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().

◆ vect_recog_sat_add_pattern()

◆ vect_recog_sat_sub_pattern()

◆ vect_recog_sat_sub_pattern_transform()

◆ vect_recog_sat_trunc_pattern()

◆ vect_recog_temp_ssa_var()

static tree vect_recog_temp_ssa_var ( tree type,
gimple * stmt = NULL )
static

◆ vect_recog_vector_vector_shift_pattern()

static gimple * vect_recog_vector_vector_shift_pattern ( vec_info * vinfo,
stmt_vec_info stmt_vinfo,
tree * type_out )
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().

◆ vect_recog_widen_abd_pattern()

◆ vect_recog_widen_minus_pattern()

static gimple * vect_recog_widen_minus_pattern ( vec_info * vinfo,
stmt_vec_info last_stmt_info,
tree * type_out )
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().

◆ vect_recog_widen_mult_pattern()

static gimple * vect_recog_widen_mult_pattern ( vec_info * vinfo,
stmt_vec_info last_stmt_info,
tree * type_out )
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().

◆ vect_recog_widen_op_pattern()

static gimple * vect_recog_widen_op_pattern ( vec_info * vinfo,
stmt_vec_info last_stmt_info,
tree * type_out,
tree_code orig_code,
code_helper wide_code,
bool shift_p,
const char * name )
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().

◆ vect_recog_widen_plus_pattern()

static gimple * vect_recog_widen_plus_pattern ( vec_info * vinfo,
stmt_vec_info last_stmt_info,
tree * type_out )
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().

◆ vect_recog_widen_shift_pattern()

static gimple * vect_recog_widen_shift_pattern ( vec_info * vinfo,
stmt_vec_info last_stmt_info,
tree * type_out )
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().

◆ vect_recog_widen_sum_pattern()

static gimple * vect_recog_widen_sum_pattern ( vec_info * vinfo,
stmt_vec_info stmt_vinfo,
tree * type_out )
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().

◆ vect_set_min_input_precision()

static void vect_set_min_input_precision ( stmt_vec_info stmt_info,
tree type,
unsigned int min_input_precision )
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().

◆ vect_set_operation_type()

static void vect_set_operation_type ( stmt_vec_info stmt_info,
tree type,
unsigned int precision,
signop sign )
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().

◆ vect_set_pattern_stmt()

static void vect_set_pattern_stmt ( vec_info * vinfo,
gimple * pattern_stmt,
stmt_vec_info orig_stmt_info,
tree vectype )
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().

◆ vect_split_statement()

static bool vect_split_statement ( vec_info * vinfo,
stmt_vec_info stmt2_info,
tree new_rhs,
gimple * stmt1,
tree vectype )
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().

◆ vect_supportable_conv_optab_p()

static bool vect_supportable_conv_optab_p ( vec_info * vinfo,
tree otype,
tree_code code,
tree itype,
tree * vecotype_out,
tree * vecitype_out = NULL,
enum optab_subtype subtype = optab_default )
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().

◆ vect_supportable_direct_optab_p()

static bool vect_supportable_direct_optab_p ( vec_info * vinfo,
tree otype,
tree_code code,
tree itype,
tree * vecotype_out,
tree * vecitype_out = NULL,
enum optab_subtype subtype = optab_default )
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().

◆ vect_synth_mult_by_constant()

static gimple * vect_synth_mult_by_constant ( vec_info * vinfo,
tree op,
tree val,
stmt_vec_info stmt_vinfo )
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().

◆ vect_truncatable_operation_p()

static bool vect_truncatable_operation_p ( tree_code code)
static
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().

◆ vect_widened_op_tree()

static unsigned int vect_widened_op_tree ( vec_info * vinfo,
stmt_vec_info stmt_info,
tree_code code,
code_helper widened_code,
bool shift_p,
unsigned int max_nops,
vect_unpromoted_value * unprom,
tree * common_type,
enum optab_subtype * subtype = NULL )
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().

Variable Documentation

◆ vect_vect_recog_func_ptrs

vect_recog_func vect_vect_recog_func_ptrs[]
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().