GCC Middle and Back End API Reference
tree-vect-slp.c File Reference
#include "optabs.h"
Include dependency graph for tree-vect-slp.c:

Functions

LOC find_bb_location ()
static void vect_free_slp_tree ()
void vect_free_slp_instance ()
static slp_tree vect_create_new_slp_node ()
static vec< slp_oprnd_infovect_create_oprnd_info ()
static void vect_free_oprnd_info ()
static int vect_get_place_in_interleaving_chain ()
static bool vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, gimple stmt, bool first, vec< slp_oprnd_info > *oprnds_info)
static bool vect_build_slp_tree_1 (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, vec< gimple > stmts, unsigned int group_size, unsigned nops, unsigned int *max_nunits, unsigned int vectorization_factor, bool *matches)
static bool vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, slp_tree *node, unsigned int group_size, unsigned int *max_nunits, vec< slp_tree > *loads, unsigned int vectorization_factor, bool *matches, unsigned *npermutes)
static void vect_print_slp_tree ()
static void vect_mark_slp_stmts ()
static void vect_mark_slp_stmts_relevant ()
static void vect_slp_rearrange_stmts (slp_tree node, unsigned int group_size, vec< unsigned > permutation)
static bool vect_supported_load_permutation_p ()
static gimple vect_find_first_load_in_slp_instance ()
static gimple vect_find_last_store_in_slp_instance ()
static void vect_analyze_slp_cost_1 (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, slp_instance instance, slp_tree node, stmt_vector_for_cost *prologue_cost_vec, unsigned ncopies_for_cost)
static void vect_analyze_slp_cost (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, slp_instance instance, unsigned nunits)
static bool vect_analyze_slp_instance (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, gimple stmt)
bool vect_analyze_slp ()
bool vect_make_slp_decision ()
static void vect_detect_hybrid_slp_stmts ()
void vect_detect_hybrid_slp ()
static bb_vec_info new_bb_vec_info ()
static void destroy_bb_vec_info ()
static bool vect_slp_analyze_node_operations ()
static bool vect_slp_analyze_operations ()
static unsigned vect_bb_slp_scalar_cost (basic_block bb, slp_tree node, vec< bool, va_stack > life)
static bool vect_bb_vectorization_profitable_p ()
static bb_vec_info vect_slp_analyze_bb_1 ()
bb_vec_info vect_slp_analyze_bb ()
void vect_update_slp_costs_according_to_vf ()
static void vect_get_constant_vectors (tree op, slp_tree slp_node, vec< tree > *vec_oprnds, unsigned int op_num, unsigned int number_of_vectors, int reduc_index)
static void vect_get_slp_vect_defs ()
void vect_get_slp_defs (vec< tree > ops, slp_tree slp_node, vec< vec< tree > > *vec_oprnds, int reduc_index)
static void vect_create_mask_and_perm (gimple stmt, gimple next_scalar_stmt, tree mask, int first_vec_indx, int second_vec_indx, gimple_stmt_iterator *gsi, slp_tree node, tree vectype, vec< tree > dr_chain, int ncopies, int vect_stmts_counter)
static bool vect_get_mask_element (gimple stmt, int first_mask_element, int m, int mask_nunits, bool only_one_vec, int index, unsigned char *mask, int *current_mask_element, bool *need_next_vector, int *number_of_mask_fixes, bool *mask_fixed, bool *needs_first_vector)
bool vect_transform_slp_perm_load (slp_tree node, vec< tree > dr_chain, gimple_stmt_iterator *gsi, int vf, slp_instance slp_node_instance, bool analyze_only)
static bool vect_schedule_slp_instance (slp_tree node, slp_instance instance, unsigned int vectorization_factor)
static void vect_remove_slp_scalar_calls ()
bool vect_schedule_slp ()
void vect_slp_transform_bb ()

Function Documentation

static void destroy_bb_vec_info ( )
static
LOC find_bb_location ( )
@verbatim SLP - Basic Block Vectorization

Copyright (C) 2007-2013 Free Software Foundation, Inc. Contributed by Dorit Naishlos dorit.nosp@m.@il..nosp@m.ibm.c.nosp@m.om and Ira Rosen irar@.nosp@m.il.i.nosp@m.bm.co.nosp@m.m

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/.

Extract the location of the basic block in the source code.
   Return the basic block location if succeed and NULL if not.   

References gimple_location(), gsi_end_p(), gsi_next(), gsi_start_bb(), gsi_stmt(), and si.

Referenced by execute_vect_slp().

static bb_vec_info new_bb_vec_info ( )
static
Create and initialize a new bb_vec_info struct for BB, as well as
   stmt_vec_info structs for all the stmts in it.   

References basic_block_def::aux, gimple_set_uid(), gsi_end_p(), gsi_next(), gsi_start_bb(), gsi_stmt(), init_cost(), new_stmt_vec_info(), and set_vinfo_for_stmt().

Referenced by vect_slp_analyze_bb_1().

bool vect_analyze_slp ( )
Check if there are stmts in the loop can be vectorized using SLP.  Build SLP
   trees of packed scalar stmts if SLP is possible.   

References dump_enabled_p(), dump_printf_loc(), vect_analyze_slp_instance(), vect_location, and vNULL.

Referenced by vect_analyze_loop_2(), and vect_slp_analyze_bb_1().

static void vect_analyze_slp_cost ( loop_vec_info  loop_vinfo,
bb_vec_info  bb_vinfo,
slp_instance  instance,
unsigned  nunits 
)
static
static void vect_analyze_slp_cost_1 ( loop_vec_info  loop_vinfo,
bb_vec_info  bb_vinfo,
slp_instance  instance,
slp_tree  node,
stmt_vector_for_cost prologue_cost_vec,
unsigned  ncopies_for_cost 
)
static
static bool vect_analyze_slp_instance ( loop_vec_info  loop_vinfo,
bb_vec_info  bb_vinfo,
gimple  stmt 
)
static
static unsigned vect_bb_slp_scalar_cost ( basic_block  bb,
slp_tree  node,
vec< bool, va_stack life 
)
static
Compute the scalar cost of the SLP node NODE and its children
   and return it.  Do not account defs that are marked in LIFE and
   update LIFE according to uses of NODE.   

References DR_IS_READ, scalar_load, scalar_stmt, scalar_store, stmt_cost(), vect_get_stmt_cost(), and vinfo_for_stmt().

Referenced by vect_bb_vectorization_profitable_p().

static bool vect_build_slp_tree ( loop_vec_info  loop_vinfo,
bb_vec_info  bb_vinfo,
slp_tree node,
unsigned int  group_size,
unsigned int *  max_nunits,
vec< slp_tree > *  loads,
unsigned int  vectorization_factor,
bool *  matches,
unsigned *  npermutes 
)
static
Recursively build an SLP tree starting from NODE.
   Fail (and return a value not equal to zero) if def-stmts are not
   isomorphic, require data permutation or are of unsupported types of
   operation.  Otherwise, return 0.
   The value returned is the depth in the SLP tree where a mismatch
   was found.   

References commutative_tree_code(), _slp_oprnd_info::def_stmts, DR_IS_READ, _slp_oprnd_info::first_dt, gimple_assign_rhs_code(), gimple_call_num_args(), gimple_num_ops(), is_gimple_assign(), is_gimple_call(), data_reference::stmt, vect_build_slp_tree_1(), vect_create_new_slp_node(), vect_create_oprnd_info(), vect_free_oprnd_info(), vect_free_slp_tree(), vect_get_and_check_slp_defs(), vect_internal_def, vinfo_for_stmt(), and vNULL.

Referenced by vect_analyze_slp_instance().

static bool vect_build_slp_tree_1 ( loop_vec_info  loop_vinfo,
bb_vec_info  bb_vinfo,
vec< gimple stmts,
unsigned int  group_size,
unsigned  nops,
unsigned int *  max_nunits,
unsigned int  vectorization_factor,
bool *  matches 
)
static
static void vect_create_mask_and_perm ( gimple  stmt,
gimple  next_scalar_stmt,
tree  mask,
int  first_vec_indx,
int  second_vec_indx,
gimple_stmt_iterator gsi,
slp_tree  node,
tree  vectype,
vec< tree dr_chain,
int  ncopies,
int  vect_stmts_counter 
)
inlinestatic
Create NCOPIES permutation statements using the mask MASK_BYTES (by
   building a vector of type MASK_TYPE from it) and two input vectors placed in
   DR_CHAIN at FIRST_VEC_INDX and SECOND_VEC_INDX for the first copy and
   shifting by STRIDE elements of DR_CHAIN for every copy.
   (STRIDE is the number of vectorized stmts for NODE divided by the number of
   copies).
   VECT_STMTS_COUNTER specifies the index in the vectorized stmts of NODE, where
   the created stmts must be inserted.   

References gimple_assign_lhs(), gimple_build_assign_with_ops(), gimple_set_lhs(), make_ssa_name(), vect_create_destination_var(), vect_finish_stmt_generation(), and vinfo_for_stmt().

Referenced by vect_transform_slp_perm_load().

static slp_tree vect_create_new_slp_node ( )
static
static vec<slp_oprnd_info> vect_create_oprnd_info ( )
static
Allocate operands info for NOPS operands, and GROUP_SIZE def-stmts for each
   operand.   

References _slp_oprnd_info::def_stmts, _slp_oprnd_info::first_dt, _slp_oprnd_info::first_op_type, _slp_oprnd_info::first_pattern, and vect_uninitialized_def.

Referenced by vect_build_slp_tree().

void vect_detect_hybrid_slp ( )
Find stmts that must be both vectorized and SLPed.   

References dump_enabled_p(), dump_printf_loc(), vect_detect_hybrid_slp_stmts(), and vect_location.

Referenced by vect_analyze_loop_2().

static void vect_detect_hybrid_slp_stmts ( )
static
Find stmts that must be both vectorized and SLPed (since they feed stmts that
   can't be SLPed) in the tree rooted at NODE.  Mark such stmts as HYBRID.   

References flow_bb_inside_loop_p(), gimple_op(), hybrid, data_reference::stmt, vect_mark_slp_stmts(), vect_reduction_def, and vinfo_for_stmt().

Referenced by vect_detect_hybrid_slp().

static gimple vect_find_first_load_in_slp_instance ( )
static
Find the first load in the loop that belongs to INSTANCE.
   When loads are in several SLP nodes, there can be a case in which the first
   load does not appear in the first SLP node to be transformed, causing
   incorrect order of statements.  Since we generate all the loads together,
   they must be inserted before the first load of the SLP instance and not
   before the first load of the first node of the instance.   

References get_earlier_stmt().

Referenced by vect_analyze_slp_instance().

static gimple vect_find_last_store_in_slp_instance ( )
static
Find the last store in SLP INSTANCE.   

References get_later_stmt().

Referenced by vect_schedule_slp_instance().

static void vect_free_oprnd_info ( )
static
Free operands info.   

References _slp_oprnd_info::def_stmts.

Referenced by vect_build_slp_tree().

void vect_free_slp_instance ( )
Free the memory allocated for the SLP instance.   

References free(), and vect_free_slp_tree().

Referenced by destroy_bb_vec_info(), destroy_loop_vec_info(), vect_analyze_slp_instance(), and vect_slp_analyze_operations().

static void vect_free_slp_tree ( )
static
Recursively free the memory allocated for the SLP tree rooted at NODE.   

References free().

Referenced by vect_analyze_slp_instance(), vect_build_slp_tree(), and vect_free_slp_instance().

static bool vect_get_and_check_slp_defs ( loop_vec_info  loop_vinfo,
bb_vec_info  bb_vinfo,
gimple  stmt,
bool  first,
vec< slp_oprnd_info > *  oprnds_info 
)
static
static void vect_get_constant_vectors ( tree  op,
slp_tree  slp_node,
vec< tree > *  vec_oprnds,
unsigned int  op_num,
unsigned int  number_of_vectors,
int  reduc_index 
)
static
For constant and loop invariant defs of SLP_NODE this function returns
   (vector) defs (VEC_OPRNDS) that will be used in the vectorized stmts.
   OP_NUM determines if we gather defs for operand 0 or operand 1 of the RHS of
   scalar stmts.  NUMBER_OF_VECTORS is the number of vector defs to create.
   REDUC_INDEX is the index of the reduction operand in the statements, unless
   it is -1.   

References build_constructor(), build_int_cst(), build_real(), build_vector_from_val(), dconst0, dconst1, get_vectype_for_scalar_type(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs3(), gimple_bb(), gimple_build_assign_with_ops(), gimple_call_arg(), gimple_expr_code(), gimple_op(), gimple_seq_add_stmt(), gsi_for_stmt(), gsi_insert_seq_before_without_update(), GSI_SAME_STMT, least_common_multiple(), loop_preheader_edge(), make_ssa_name(), types_compatible_p(), vec_alloc(), vect_init_vector(), vect_reduction_def, and vinfo_for_stmt().

Referenced by vect_get_slp_defs().

static bool vect_get_mask_element ( gimple  stmt,
int  first_mask_element,
int  m,
int  mask_nunits,
bool  only_one_vec,
int  index,
unsigned char *  mask,
int *  current_mask_element,
bool *  need_next_vector,
int *  number_of_mask_fixes,
bool *  mask_fixed,
bool *  needs_first_vector 
)
static
Given FIRST_MASK_ELEMENT - the mask element in element representation,
   return in CURRENT_MASK_ELEMENT its equivalent in target specific
   representation.  Check that the mask is valid and return FALSE if not.
   Return TRUE in NEED_NEXT_VECTOR if the permutation requires to move to
   the next vector, i.e., the current first vector is not needed.   

References dump_enabled_p(), dump_gimple_stmt(), dump_printf_loc(), and vect_location.

Referenced by vect_transform_slp_perm_load().

static int vect_get_place_in_interleaving_chain ( )
static
Find the place of the data-ref in STMT in the interleaving chain that starts
   from FIRST_STMT.  Return -1 if the data-ref is not a part of the chain.   

References first_stmt(), and vinfo_for_stmt().

Referenced by vect_analyze_slp_cost_1(), and vect_analyze_slp_instance().

void vect_get_slp_defs ( vec< tree ops,
slp_tree  slp_node,
vec< vec< tree > > *  vec_oprnds,
int  reduc_index 
)
Get vectorized definitions for SLP_NODE.
   If the scalar definitions are loop invariants or constants, collect them and
   call vect_get_constant_vectors() to create vector stmts.
   Otherwise, the def-stmts must be already vectorized and the vectorized stmts
   must be stored in the corresponding child of SLP_NODE, and we call
   vect_get_slp_vect_defs () to retrieve them.   

References first_stmt(), gimple_get_lhs(), HOST_WIDE_INT, operand_equal_p(), vect_get_constant_vectors(), vect_get_slp_vect_defs(), vect_get_smallest_scalar_type(), vinfo_for_stmt(), and vNULL.

Referenced by vect_get_vec_defs(), vectorizable_call(), and vectorizable_condition().

static void vect_get_slp_vect_defs ( )
static
Get vectorized definitions from SLP_NODE that contains corresponding
   vectorized def-stmts.   

References gimple_get_lhs().

Referenced by vect_get_slp_defs().

bool vect_make_slp_decision ( )
For each possible SLP instance decide whether to SLP it and calculate overall
   unrolling factor needed to SLP the loop.  Return TRUE if decided to SLP at
   least one instance.   

References dump_enabled_p(), dump_printf_loc(), pure_slp, vect_location, and vect_mark_slp_stmts().

Referenced by vect_analyze_loop_2().

static void vect_mark_slp_stmts ( )
static
Mark the tree rooted at NODE with MARK (PURE_SLP or HYBRID).
   If MARK is HYBRID, it refers to a specific stmt in NODE (the stmt at index
   J).  Otherwise, MARK is PURE_SLP and J is -1, which indicates that all the
   stmts in NODE are to be marked.   

References data_reference::stmt, and vinfo_for_stmt().

Referenced by vect_detect_hybrid_slp_stmts(), vect_make_slp_decision(), and vect_slp_analyze_bb_1().

static void vect_mark_slp_stmts_relevant ( )
static
Mark the statements of the tree rooted at NODE as relevant (vect_used).   

References data_reference::stmt, vect_used_in_scope, and vinfo_for_stmt().

Referenced by vect_slp_analyze_bb_1().

static void vect_print_slp_tree ( )
static
Dump a slp tree NODE using flags specified in DUMP_KIND.   

References dump_gimple_stmt(), dump_printf(), and data_reference::stmt.

Referenced by vect_analyze_slp_instance().

static void vect_remove_slp_scalar_calls ( )
static
Replace scalar calls from SLP node NODE with setting of their lhs to zero.
   For loop vectorization this is done in vectorizable_call, but for SLP
   it needs to be deferred until end of vect_schedule_slp, because multiple
   SLP instances may refer to the same scalar stmt.   

References build_zero_cst(), gimple_assign_lhs(), gimple_call_lhs(), gsi_for_stmt(), gsi_replace(), is_gimple_call(), is_pattern_stmt_p(), set_vinfo_for_stmt(), and vinfo_for_stmt().

Referenced by vect_schedule_slp().

static bool vect_schedule_slp_instance ( slp_tree  node,
slp_instance  instance,
unsigned int  vectorization_factor 
)
static
static bool vect_slp_analyze_node_operations ( )
static
Analyze statements contained in SLP tree node after recursively analyzing
   the subtree. Return TRUE if the operations are supported.   

References vect_analyze_stmt(), and vinfo_for_stmt().

Referenced by vect_slp_analyze_operations().

static bool vect_slp_analyze_operations ( )
static
Analyze statements in SLP instances of the basic block.  Return TRUE if the
   operations are supported.  

References vect_free_slp_instance(), and vect_slp_analyze_node_operations().

Referenced by vect_slp_analyze_bb_1().

static void vect_slp_rearrange_stmts ( slp_tree  node,
unsigned int  group_size,
vec< unsigned >  permutation 
)
static
Rearrange the statements of NODE according to PERMUTATION.   

References data_reference::stmt.

Referenced by vect_supported_load_permutation_p().

bool vect_transform_slp_perm_load ( slp_tree  node,
vec< tree dr_chain,
gimple_stmt_iterator gsi,
int  vf,
slp_instance  slp_node_instance,
bool  analyze_only 
)
Generate vector permute statements from a list of loads in DR_CHAIN.
   If ANALYZE_ONLY is TRUE, only check that it is possible to create valid
   permute statements for the SLP node NODE of the SLP instance
   SLP_NODE_INSTANCE.   

References build_int_cst(), can_vec_perm_p(), dump_enabled_p(), dump_gimple_stmt(), dump_printf(), dump_printf_loc(), get_vectype_for_scalar_type(), int_mode_for_mode(), lang_hooks_for_types::type_for_mode, lang_hooks::types, vect_create_mask_and_perm(), vect_get_mask_element(), vect_location, and vinfo_for_stmt().

Referenced by vect_supported_load_permutation_p(), and vectorizable_load().

void vect_update_slp_costs_according_to_vf ( )
SLP costs are calculated according to SLP instance unrolling factor (i.e.,
   the number of created vector stmts depends on the unrolling factor).
   However, the actual number of vector stmts for every SLP node depends on
   VF which is set later in vect_analyze_operations ().  Hence, SLP costs
   should be updated.  In this function we assume that the inside costs
   calculated in vect_model_xxx_cost are linear in ncopies.   

References add_stmt_cost(), _stmt_info_for_cost::count, dump_enabled_p(), dump_printf_loc(), _stmt_info_for_cost::kind, _stmt_info_for_cost::misalign, si, _stmt_info_for_cost::stmt, vect_body, vect_location, and vinfo_for_stmt().

Referenced by vect_analyze_loop_operations().