X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gcc%2Ftree-vectorizer.h;h=4c5ea36017d1e407e64c30acdcb7a6827051728a;hb=3f30a9a6aabcc7408bec1e42736889e3edd9f289;hp=11795d88632f34e87486e752e048c99b18800400;hpb=35e1a5e7cf85b08634a46b08e76d28ced021aff9;p=platform%2Fupstream%2Fgcc.git diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 11795d8..4c5ea36 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -1,5 +1,5 @@ /* Vectorizer - Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 + Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. Contributed by Dorit Naishlos @@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see #define GCC_TREE_VECTORIZER_H #include "tree-data-ref.h" +#include "target.h" typedef source_location LOC; #define UNKNOWN_LOC UNKNOWN_LOCATION @@ -70,34 +71,18 @@ enum vect_def_type { || ((D) == vect_double_reduction_def) \ || ((D) == vect_nested_cycle)) -/* Define verbosity levels. */ -enum verbosity_levels { - REPORT_NONE, - REPORT_VECTORIZED_LOCATIONS, - REPORT_UNVECTORIZED_LOCATIONS, - REPORT_COST, - REPORT_ALIGNMENT, - REPORT_DR_DETAILS, - REPORT_BAD_FORM_LOOPS, - REPORT_OUTER_LOOPS, - REPORT_SLP, - REPORT_DETAILS, - /* New verbosity levels should be added before this one. */ - MAX_VERBOSITY_LEVEL -}; - /************************************************************************ SLP ************************************************************************/ +typedef void *slp_void_p; +DEF_VEC_P (slp_void_p); +DEF_VEC_ALLOC_P (slp_void_p, heap); -/* A computation tree of an SLP instance. Each node corresponds to a group of +/* A computation tree of an SLP instance. Each node corresponds to a group of stmts to be packed in a SIMD stmt. */ typedef struct _slp_tree { - /* Only binary and unary operations are supported. LEFT child corresponds to - the first operand and RIGHT child to the second if the operation is - binary. */ - struct _slp_tree *left; - struct _slp_tree *right; + /* Nodes that contain def-stmts of this node statements operands. */ + VEC (slp_void_p, heap) *children; /* A group of scalar stmts to be vectorized together. */ VEC (gimple, heap) *stmts; /* Vectorized stmt/s. */ @@ -162,14 +147,47 @@ DEF_VEC_ALLOC_P(slp_instance, heap); #define SLP_INSTANCE_LOADS(S) (S)->loads #define SLP_INSTANCE_FIRST_LOAD_STMT(S) (S)->first_load -#define SLP_TREE_LEFT(S) (S)->left -#define SLP_TREE_RIGHT(S) (S)->right +#define SLP_TREE_CHILDREN(S) (S)->children #define SLP_TREE_SCALAR_STMTS(S) (S)->stmts #define SLP_TREE_VEC_STMTS(S) (S)->vec_stmts #define SLP_TREE_NUMBER_OF_VEC_STMTS(S) (S)->vec_stmts_size #define SLP_TREE_OUTSIDE_OF_LOOP_COST(S) (S)->cost.outside_of_loop #define SLP_TREE_INSIDE_OF_LOOP_COST(S) (S)->cost.inside_of_loop +/* This structure is used in creation of an SLP tree. Each instance + corresponds to the same operand in a group of scalar stmts in an SLP + node. */ +typedef struct _slp_oprnd_info +{ + /* Def-stmts for the operands. */ + VEC (gimple, heap) *def_stmts; + /* Information about the first statement, its vector def-type, type, the + operand itself in case it's constant, and an indication if it's a pattern + stmt. */ + enum vect_def_type first_dt; + tree first_def_type; + tree first_const_oprnd; + bool first_pattern; +} *slp_oprnd_info; + +DEF_VEC_P(slp_oprnd_info); +DEF_VEC_ALLOC_P(slp_oprnd_info, heap); + + +typedef struct _vect_peel_info +{ + int npeel; + struct data_reference *dr; + unsigned int count; +} *vect_peel_info; + +typedef struct _vect_peel_extended_info +{ + struct _vect_peel_info peel_info; + unsigned int inside_cost; + unsigned int outside_cost; +} *vect_peel_extended_info; + /*-----------------------------------------------------------------*/ /* Info on vectorized loops. */ /*-----------------------------------------------------------------*/ @@ -217,6 +235,9 @@ typedef struct _loop_vec_info { /* The mask used to check the alignment of pointers or arrays. */ int ptr_mask; + /* The loop nest in which the data dependences are computed. */ + VEC (loop_p, heap) *loop_nest; + /* All data references in the loop. */ VEC (data_reference_p, heap) *datarefs; @@ -233,9 +254,9 @@ typedef struct _loop_vec_info { /* All interleaving chains of stores in the loop, represented by the first stmt in the chain. */ - VEC(gimple, heap) *strided_stores; + VEC(gimple, heap) *grouped_stores; - /* All SLP instances in the loop. This is a subset of the set of STRIDED_STORES + /* All SLP instances in the loop. This is a subset of the set of GROUP_STORES of the loop. */ VEC(slp_instance, heap) *slp_instances; @@ -245,6 +266,19 @@ typedef struct _loop_vec_info { /* Reduction cycles detected in the loop. Used in loop-aware SLP. */ VEC (gimple, heap) *reductions; + + /* All reduction chains in the loop, represented by the first + stmt in the chain. */ + VEC (gimple, heap) *reduction_chains; + + /* Hash table used to choose the best peeling option. */ + htab_t peeling_htab; + + /* When we have grouped data accesses with gaps, we may introduce invalid + memory accesses. We peel the last iteration of the loop to prevent + this. */ + bool peeling_for_gaps; + } *loop_vec_info; /* Access Functions. */ @@ -258,6 +292,7 @@ typedef struct _loop_vec_info { #define LOOP_VINFO_VECTORIZABLE_P(L) (L)->vectorizable #define LOOP_VINFO_VECT_FACTOR(L) (L)->vectorization_factor #define LOOP_VINFO_PTR_MASK(L) (L)->ptr_mask +#define LOOP_VINFO_LOOP_NEST(L) (L)->loop_nest #define LOOP_VINFO_DATAREFS(L) (L)->datarefs #define LOOP_VINFO_DDRS(L) (L)->ddrs #define LOOP_VINFO_INT_NITERS(L) (TREE_INT_CST_LOW ((L)->num_iters)) @@ -266,10 +301,13 @@ typedef struct _loop_vec_info { #define LOOP_VINFO_MAY_MISALIGN_STMTS(L) (L)->may_misalign_stmts #define LOOP_VINFO_LOC(L) (L)->loop_line_number #define LOOP_VINFO_MAY_ALIAS_DDRS(L) (L)->may_alias_ddrs -#define LOOP_VINFO_STRIDED_STORES(L) (L)->strided_stores +#define LOOP_VINFO_GROUPED_STORES(L) (L)->grouped_stores #define LOOP_VINFO_SLP_INSTANCES(L) (L)->slp_instances #define LOOP_VINFO_SLP_UNROLLING_FACTOR(L) (L)->slp_unrolling_factor #define LOOP_VINFO_REDUCTIONS(L) (L)->reductions +#define LOOP_VINFO_REDUCTION_CHAINS(L) (L)->reduction_chains +#define LOOP_VINFO_PEELING_HTAB(L) (L)->peeling_htab +#define LOOP_VINFO_PEELING_FOR_GAPS(L) (L)->peeling_for_gaps #define LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT(L) \ VEC_length (gimple, (L)->may_misalign_stmts) > 0 @@ -301,10 +339,10 @@ typedef struct _bb_vec_info { basic_block bb; /* All interleaving chains of stores in the basic block, represented by the first stmt in the chain. */ - VEC(gimple, heap) *strided_stores; + VEC(gimple, heap) *grouped_stores; /* All SLP instances in the basic block. This is a subset of the set of - STRIDED_STORES of the basic block. */ + GROUP_STORES of the basic block. */ VEC(slp_instance, heap) *slp_instances; /* All data references in the basic block. */ @@ -315,7 +353,7 @@ typedef struct _bb_vec_info { } *bb_vec_info; #define BB_VINFO_BB(B) (B)->bb -#define BB_VINFO_STRIDED_STORES(B) (B)->strided_stores +#define BB_VINFO_GROUPED_STORES(B) (B)->grouped_stores #define BB_VINFO_SLP_INSTANCES(B) (B)->slp_instances #define BB_VINFO_DATAREFS(B) (B)->datarefs #define BB_VINFO_DDRS(B) (B)->ddrs @@ -333,6 +371,7 @@ enum stmt_vec_info_type { undef_vec_info_type = 0, load_vec_info_type, store_vec_info_type, + shift_vec_info_type, op_vec_info_type, call_vec_info_type, assignment_vec_info_type, @@ -438,6 +477,13 @@ typedef struct _stmt_vec_info { tree dr_step; tree dr_aligned_to; + /* For loop PHI nodes, the evolution part of it. This makes sure + this information is still available in vect_update_ivs_after_vectorizer + where we may not be able to re-analyze the PHI nodes evolution as + peeling for the prologue loop can make it unanalyzable. The evolution + part is still correct though. */ + tree loop_phi_evolution_part; + /* Used for various bookkeeping purposes, generally holding a pointer to some other stmt S that is in some way "related" to this stmt. Current use of this field is: @@ -449,6 +495,9 @@ typedef struct _stmt_vec_info { pattern). */ gimple related_stmt; + /* Used to keep a sequence of def stmts of a pattern stmt if such exists. */ + gimple_seq pattern_def_seq; + /* List of datarefs that are known to have the same alignment as the dataref of this stmt. */ VEC(dr_p,heap) *same_align_refs; @@ -459,15 +508,15 @@ typedef struct _stmt_vec_info { /* Whether the stmt is SLPed, loop-based vectorized, or both. */ enum slp_vect_type slp_type; - /* Interleaving info. */ - /* First data-ref in the interleaving group. */ - gimple first_dr; - /* Pointer to the next data-ref in the group. */ - gimple next_dr; - /* In case that two or more stmts share data-ref, this is the pointer to the - previously detected stmt with the same dr. */ + /* Interleaving and reduction chains info. */ + /* First element in the group. */ + gimple first_element; + /* Pointer to the next element in the group. */ + gimple next_element; + /* For data-refs, in case that two or more stmts share data-ref, this is the + pointer to the previously detected stmt with the same dr. */ gimple same_dr_stmt; - /* The size of the interleaving group. */ + /* The size of the group. */ unsigned int size; /* For stores, number of stores from this group seen. We vectorize the last one. */ @@ -494,6 +543,10 @@ typedef struct _stmt_vec_info { /* Is this statement vectorizable or should it be skipped in (partial) vectorization. */ bool vectorizable; + + /* For loads only, true if this is a gather load. */ + bool gather_p; + bool stride_load_p; } *stmt_vec_info; /* Access Functions. */ @@ -507,6 +560,8 @@ typedef struct _stmt_vec_info { #define STMT_VINFO_VEC_STMT(S) (S)->vectorized_stmt #define STMT_VINFO_VECTORIZABLE(S) (S)->vectorizable #define STMT_VINFO_DATA_REF(S) (S)->data_ref_info +#define STMT_VINFO_GATHER_P(S) (S)->gather_p +#define STMT_VINFO_STRIDE_LOAD_P(S) (S)->stride_load_p #define STMT_VINFO_DR_BASE_ADDRESS(S) (S)->dr_base_address #define STMT_VINFO_DR_INIT(S) (S)->dr_init @@ -516,24 +571,26 @@ typedef struct _stmt_vec_info { #define STMT_VINFO_IN_PATTERN_P(S) (S)->in_pattern_p #define STMT_VINFO_RELATED_STMT(S) (S)->related_stmt +#define STMT_VINFO_PATTERN_DEF_SEQ(S) (S)->pattern_def_seq #define STMT_VINFO_SAME_ALIGN_REFS(S) (S)->same_align_refs #define STMT_VINFO_DEF_TYPE(S) (S)->def_type -#define STMT_VINFO_DR_GROUP_FIRST_DR(S) (S)->first_dr -#define STMT_VINFO_DR_GROUP_NEXT_DR(S) (S)->next_dr -#define STMT_VINFO_DR_GROUP_SIZE(S) (S)->size -#define STMT_VINFO_DR_GROUP_STORE_COUNT(S) (S)->store_count -#define STMT_VINFO_DR_GROUP_GAP(S) (S)->gap -#define STMT_VINFO_DR_GROUP_SAME_DR_STMT(S)(S)->same_dr_stmt -#define STMT_VINFO_DR_GROUP_READ_WRITE_DEPENDENCE(S) (S)->read_write_dep -#define STMT_VINFO_STRIDED_ACCESS(S) ((S)->first_dr != NULL) - -#define DR_GROUP_FIRST_DR(S) (S)->first_dr -#define DR_GROUP_NEXT_DR(S) (S)->next_dr -#define DR_GROUP_SIZE(S) (S)->size -#define DR_GROUP_STORE_COUNT(S) (S)->store_count -#define DR_GROUP_GAP(S) (S)->gap -#define DR_GROUP_SAME_DR_STMT(S) (S)->same_dr_stmt -#define DR_GROUP_READ_WRITE_DEPENDENCE(S) (S)->read_write_dep +#define STMT_VINFO_GROUP_FIRST_ELEMENT(S) (S)->first_element +#define STMT_VINFO_GROUP_NEXT_ELEMENT(S) (S)->next_element +#define STMT_VINFO_GROUP_SIZE(S) (S)->size +#define STMT_VINFO_GROUP_STORE_COUNT(S) (S)->store_count +#define STMT_VINFO_GROUP_GAP(S) (S)->gap +#define STMT_VINFO_GROUP_SAME_DR_STMT(S) (S)->same_dr_stmt +#define STMT_VINFO_GROUP_READ_WRITE_DEPENDENCE(S) (S)->read_write_dep +#define STMT_VINFO_GROUPED_ACCESS(S) ((S)->first_element != NULL && (S)->data_ref_info) +#define STMT_VINFO_LOOP_PHI_EVOLUTION_PART(S) (S)->loop_phi_evolution_part + +#define GROUP_FIRST_ELEMENT(S) (S)->first_element +#define GROUP_NEXT_ELEMENT(S) (S)->next_element +#define GROUP_SIZE(S) (S)->size +#define GROUP_STORE_COUNT(S) (S)->store_count +#define GROUP_GAP(S) (S)->gap +#define GROUP_SAME_DR_STMT(S) (S)->same_dr_stmt +#define GROUP_READ_WRITE_DEPENDENCE(S) (S)->read_write_dep #define STMT_VINFO_RELEVANT_P(S) ((S)->relevant != vect_unused_in_scope) #define STMT_VINFO_OUTSIDE_OF_LOOP_COST(S) (S)->cost.outside_of_loop @@ -543,6 +600,8 @@ typedef struct _stmt_vec_info { #define PURE_SLP_STMT(S) ((S)->slp_type == pure_slp) #define STMT_SLP_TYPE(S) (S)->slp_type +#define VECT_MAX_COST 1000 + /* The maximum number of intermediate steps required in multi-step type conversion. */ #define MAX_INTERM_CVT_STEPS 3 @@ -560,6 +619,8 @@ extern VEC(vec_void_p,heap) *stmt_vec_info_vec; void init_stmt_vec_info_vec (void); void free_stmt_vec_info_vec (void); +/* Return a stmt_vec_info corresponding to STMT. */ + static inline stmt_vec_info vinfo_for_stmt (gimple stmt) { @@ -567,17 +628,18 @@ vinfo_for_stmt (gimple stmt) if (uid == 0) return NULL; - gcc_assert (uid <= VEC_length (vec_void_p, stmt_vec_info_vec)); return (stmt_vec_info) VEC_index (vec_void_p, stmt_vec_info_vec, uid - 1); } +/* Set vectorizer information INFO for STMT. */ + static inline void set_vinfo_for_stmt (gimple stmt, stmt_vec_info info) { unsigned int uid = gimple_uid (stmt); if (uid == 0) { - gcc_assert (info); + gcc_checking_assert (info); uid = VEC_length (vec_void_p, stmt_vec_info_vec) + 1; gimple_set_uid (stmt, uid); VEC_safe_push (vec_void_p, heap, stmt_vec_info_vec, (vec_void_p) info); @@ -586,6 +648,8 @@ set_vinfo_for_stmt (gimple stmt, stmt_vec_info info) VEC_replace (vec_void_p, stmt_vec_info_vec, uid - 1, (vec_void_p) info); } +/* Return the earlier statement between STMT1 and STMT2. */ + static inline gimple get_earlier_stmt (gimple stmt1, gimple stmt2) { @@ -603,15 +667,46 @@ get_earlier_stmt (gimple stmt1, gimple stmt2) if (uid1 == 0 || uid2 == 0) return NULL; + gcc_checking_assert (uid1 <= VEC_length (vec_void_p, stmt_vec_info_vec) + && uid2 <= VEC_length (vec_void_p, stmt_vec_info_vec)); + + if (uid1 < uid2) + return stmt1; + else + return stmt2; +} + +/* Return the later statement between STMT1 and STMT2. */ + +static inline gimple +get_later_stmt (gimple stmt1, gimple stmt2) +{ + unsigned int uid1, uid2; + + if (stmt1 == NULL) + return stmt2; + + if (stmt2 == NULL) + return stmt1; + + uid1 = gimple_uid (stmt1); + uid2 = gimple_uid (stmt2); + + if (uid1 == 0 || uid2 == 0) + return NULL; + gcc_assert (uid1 <= VEC_length (vec_void_p, stmt_vec_info_vec)); gcc_assert (uid2 <= VEC_length (vec_void_p, stmt_vec_info_vec)); - if (uid1 < uid2) + if (uid1 > uid2) return stmt1; else return stmt2; } +/* Return TRUE if a statement represented by STMT_INFO is a part of a + pattern. */ + static inline bool is_pattern_stmt_p (stmt_vec_info stmt_info) { @@ -627,15 +722,19 @@ is_pattern_stmt_p (stmt_vec_info stmt_info) return false; } +/* Return true if BB is a loop header. */ + static inline bool is_loop_header_bb_p (basic_block bb) { if (bb == (bb->loop_father)->header) return true; - gcc_assert (EDGE_COUNT (bb->preds) == 1); + gcc_checking_assert (EDGE_COUNT (bb->preds) == 1); return false; } +/* Set inside loop vectorization cost. */ + static inline void stmt_vinfo_set_inside_of_loop_cost (stmt_vec_info stmt_info, slp_tree slp_node, int cost) @@ -646,6 +745,8 @@ stmt_vinfo_set_inside_of_loop_cost (stmt_vec_info stmt_info, slp_tree slp_node, STMT_VINFO_INSIDE_OF_LOOP_COST (stmt_info) = cost; } +/* Set inside loop vectorization cost. */ + static inline void stmt_vinfo_set_outside_of_loop_cost (stmt_vec_info stmt_info, slp_tree slp_node, int cost) @@ -656,6 +757,8 @@ stmt_vinfo_set_outside_of_loop_cost (stmt_vec_info stmt_info, slp_tree slp_node, STMT_VINFO_OUTSIDE_OF_LOOP_COST (stmt_info) = cost; } +/* Return pow2 (X). */ + static inline int vect_pow2 (int x) { @@ -667,6 +770,18 @@ vect_pow2 (int x) return res; } +/* Get cost by calling cost target builtin. */ + +static inline +int vect_get_stmt_cost (enum vect_cost_for_stmt type_of_cost) +{ + tree dummy_type = NULL; + int dummy = 0; + + return targetm.vectorize.builtin_vectorization_cost (type_of_cost, + dummy_type, dummy); +} + /*-----------------------------------------------------------------*/ /* Info on data references alignment. */ /*-----------------------------------------------------------------*/ @@ -676,12 +791,17 @@ vect_pow2 (int x) #define DR_MISALIGNMENT(DR) ((int) (size_t) (DR)->aux) #define SET_DR_MISALIGNMENT(DR, VAL) ((DR)->aux = (void *) (size_t) (VAL)) +/* Return TRUE if the data access is aligned, and FALSE otherwise. */ + static inline bool aligned_access_p (struct data_reference *data_ref_info) { return (DR_MISALIGNMENT (data_ref_info) == 0); } +/* Return TRUE if the alignment of the data access is known, and FALSE + otherwise. */ + static inline bool known_alignment_for_access_p (struct data_reference *data_ref_info) { @@ -700,19 +820,22 @@ extern LOC vect_loop_location; in tree-vect-loop-manip.c. */ extern void slpeel_make_loop_iterate_ntimes (struct loop *, tree); extern bool slpeel_can_duplicate_loop_p (const struct loop *, const_edge); -extern void vect_loop_versioning (loop_vec_info, bool, tree *, gimple_seq *); +extern void vect_loop_versioning (loop_vec_info, unsigned int, bool); extern void vect_do_peeling_for_loop_bound (loop_vec_info, tree *, - tree, gimple_seq); -extern void vect_do_peeling_for_alignment (loop_vec_info); + unsigned int, bool); +extern void vect_do_peeling_for_alignment (loop_vec_info, unsigned int, bool); extern LOC find_loop_location (struct loop *); extern bool vect_can_advance_ivs_p (loop_vec_info); /* In tree-vect-stmts.c. */ +extern unsigned int current_vector_size; extern tree get_vectype_for_scalar_type (tree); extern tree get_same_sized_vectype (tree, tree); -extern bool vect_is_simple_use (tree, loop_vec_info, bb_vec_info, gimple *, +extern bool vect_is_simple_use (tree, gimple, loop_vec_info, + bb_vec_info, gimple *, tree *, enum vect_def_type *); -extern bool vect_is_simple_use_1 (tree, loop_vec_info, bb_vec_info, gimple *, +extern bool vect_is_simple_use_1 (tree, gimple, loop_vec_info, + bb_vec_info, gimple *, tree *, enum vect_def_type *, tree *); extern bool supportable_widening_operation (enum tree_code, gimple, tree, tree, tree *, tree *, enum tree_code *, @@ -727,13 +850,12 @@ extern void free_stmt_vec_info (gimple stmt); extern tree vectorizable_function (gimple, tree, tree); extern void vect_model_simple_cost (stmt_vec_info, int, enum vect_def_type *, slp_tree); -extern void vect_model_store_cost (stmt_vec_info, int, enum vect_def_type, - slp_tree); -extern void vect_model_load_cost (stmt_vec_info, int, slp_tree); +extern void vect_model_store_cost (stmt_vec_info, int, bool, + enum vect_def_type, slp_tree); +extern void vect_model_load_cost (stmt_vec_info, int, bool, slp_tree); extern void vect_finish_stmt_generation (gimple, gimple, gimple_stmt_iterator *); extern bool vect_mark_stmts_to_be_vectorized (loop_vec_info); -extern int cost_for_stmt (gimple); extern tree vect_get_vec_def_for_operand (tree, gimple, tree *); extern tree vect_init_vector (gimple, tree, tree, gimple_stmt_iterator *); @@ -743,12 +865,19 @@ extern bool vect_transform_stmt (gimple, gimple_stmt_iterator *, extern void vect_remove_stores (gimple); extern bool vect_analyze_stmt (gimple, bool *, slp_tree); extern bool vectorizable_condition (gimple, gimple_stmt_iterator *, gimple *, - tree, int); + tree, int, slp_tree); +extern void vect_get_load_cost (struct data_reference *, int, bool, + unsigned int *, unsigned int *); +extern void vect_get_store_cost (struct data_reference *, int, unsigned int *); +extern bool vect_supportable_shift (enum tree_code, tree); +extern void vect_get_vec_defs (tree, tree, gimple, VEC (tree, heap) **, + VEC (tree, heap) **, slp_tree, int); +extern tree vect_gen_perm_mask (tree, unsigned char *); /* In tree-vect-data-refs.c. */ extern bool vect_can_force_dr_alignment_p (const_tree, unsigned int); extern enum dr_alignment_support vect_supportable_dr_alignment - (struct data_reference *); + (struct data_reference *, bool); extern tree vect_get_smallest_scalar_type (gimple, HOST_WIDE_INT *, HOST_WIDE_INT *); extern bool vect_analyze_data_ref_dependences (loop_vec_info, bb_vec_info, @@ -758,22 +887,27 @@ extern bool vect_analyze_data_refs_alignment (loop_vec_info, bb_vec_info); extern bool vect_verify_datarefs_alignment (loop_vec_info, bb_vec_info); extern bool vect_analyze_data_ref_accesses (loop_vec_info, bb_vec_info); extern bool vect_prune_runtime_alias_test_list (loop_vec_info); +extern tree vect_check_gather (gimple, loop_vec_info, tree *, tree *, + int *); +extern bool vect_check_strided_load (gimple, loop_vec_info, tree *, tree *); extern bool vect_analyze_data_refs (loop_vec_info, bb_vec_info, int *); -extern tree vect_create_data_ref_ptr (gimple, struct loop *, tree, tree *, - gimple *, bool, bool *); +extern tree vect_create_data_ref_ptr (gimple, tree, struct loop *, tree, + tree *, gimple_stmt_iterator *, + gimple *, bool, bool *); extern tree bump_vector_ptr (tree, gimple, gimple_stmt_iterator *, gimple, tree); extern tree vect_create_destination_var (tree, tree); -extern bool vect_strided_store_supported (tree); -extern bool vect_strided_load_supported (tree); -extern bool vect_permute_store_chain (VEC(tree,heap) *,unsigned int, gimple, +extern bool vect_grouped_store_supported (tree, unsigned HOST_WIDE_INT); +extern bool vect_store_lanes_supported (tree, unsigned HOST_WIDE_INT); +extern bool vect_grouped_load_supported (tree, unsigned HOST_WIDE_INT); +extern bool vect_load_lanes_supported (tree, unsigned HOST_WIDE_INT); +extern void vect_permute_store_chain (VEC(tree,heap) *,unsigned int, gimple, gimple_stmt_iterator *, VEC(tree,heap) **); extern tree vect_setup_realignment (gimple, gimple_stmt_iterator *, tree *, enum dr_alignment_support, tree, struct loop **); -extern bool vect_permute_load_chain (VEC(tree,heap) *,unsigned int, gimple, - gimple_stmt_iterator *, VEC(tree,heap) **); -extern bool vect_transform_strided_load (gimple, VEC(tree,heap) *, int, +extern void vect_transform_grouped_load (gimple, VEC(tree,heap) *, int, gimple_stmt_iterator *); +extern void vect_record_grouped_load_vectors (gimple, VEC(tree,heap) *); extern int vect_get_place_in_interleaving_chain (gimple, gimple); extern tree vect_get_new_vect_var (tree, enum vect_var_kind, const char *); extern tree vect_create_addr_base_for_vector_ref (gimple, gimple_seq *, @@ -796,7 +930,8 @@ extern bool vectorizable_induction (gimple, gimple_stmt_iterator *, gimple *); extern int vect_estimate_min_profitable_iters (loop_vec_info); extern tree get_initial_def_for_reduction (gimple, tree, tree *); extern int vect_min_worthwhile_factor (enum tree_code); - +extern int vect_get_known_peeling_cost (loop_vec_info, int, int *, int); +extern int vect_get_single_scalar_iteration_cost (loop_vec_info); /* In tree-vect-slp.c. */ extern void vect_free_slp_instance (slp_instance); @@ -806,10 +941,11 @@ extern bool vect_transform_slp_perm_load (gimple, VEC (tree, heap) *, extern bool vect_schedule_slp (loop_vec_info, bb_vec_info); extern void vect_update_slp_costs_according_to_vf (loop_vec_info); extern bool vect_analyze_slp (loop_vec_info, bb_vec_info); -extern void vect_make_slp_decision (loop_vec_info); +extern bool vect_make_slp_decision (loop_vec_info); extern void vect_detect_hybrid_slp (loop_vec_info); -extern void vect_get_slp_defs (slp_tree, VEC (tree,heap) **, - VEC (tree,heap) **, int); +extern void vect_get_slp_defs (VEC (tree, heap) *, slp_tree, + VEC (slp_void_p, heap) **, int); + extern LOC find_bb_location (basic_block); extern bb_vec_info vect_slp_analyze_bb (basic_block); extern void vect_slp_transform_bb (basic_block); @@ -818,13 +954,13 @@ extern void vect_slp_transform_bb (basic_block); /* Pattern recognition functions. Additional pattern recognition functions can (and will) be added in the future. */ -typedef gimple (* vect_recog_func_ptr) (gimple, tree *, tree *); -#define NUM_PATTERNS 4 -void vect_pattern_recog (loop_vec_info); +typedef gimple (* vect_recog_func_ptr) (VEC (gimple, heap) **, tree *, tree *); +#define NUM_PATTERNS 10 +void vect_pattern_recog (loop_vec_info, bb_vec_info); /* In tree-vectorizer.c. */ unsigned vectorize_loops (void); /* Vectorization debug information */ -extern bool vect_print_dump_info (enum verbosity_levels); +extern bool vect_print_dump_info (enum vect_verbosity_levels); #endif /* GCC_TREE_VECTORIZER_H */