|| ((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
************************************************************************/
#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
+
+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. */
/*-----------------------------------------------------------------*/
/* Reduction cycles detected in the loop. Used in loop-aware SLP. */
VEC (gimple, heap) *reductions;
+
+ /* Hash table used to choose the best peeling option. */
+ htab_t peeling_htab;
+
} *loop_vec_info;
/* Access Functions. */
#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_PEELING_HTAB(L) (L)->peeling_htab
#define LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT(L) \
VEC_length (gimple, (L)->may_misalign_stmts) > 0
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,
#define PURE_SLP_STMT(S) ((S)->slp_type == pure_slp)
#define STMT_SLP_TYPE(S) (S)->slp_type
-/* These are some defines for the initial implementation of the vectorizer's
- cost model. These will later be target specific hooks. */
-
-/* Cost of conditional taken branch. */
-#ifndef TARG_COND_TAKEN_BRANCH_COST
-#define TARG_COND_TAKEN_BRANCH_COST 3
-#endif
-
-/* Cost of conditional not taken branch. */
-#ifndef TARG_COND_NOT_TAKEN_BRANCH_COST
-#define TARG_COND_NOT_TAKEN_BRANCH_COST 1
-#endif
-
-/* Cost of any scalar operation, excluding load and store. */
-#ifndef TARG_SCALAR_STMT_COST
-#define TARG_SCALAR_STMT_COST 1
-#endif
-
-/* Cost of scalar load. */
-#ifndef TARG_SCALAR_LOAD_COST
-#define TARG_SCALAR_LOAD_COST 1
-#endif
-
-/* Cost of scalar store. */
-#ifndef TARG_SCALAR_STORE_COST
-#define TARG_SCALAR_STORE_COST 1
-#endif
-
-/* Cost of any vector operation, excluding load, store or vector to scalar
- operation. */
-#ifndef TARG_VEC_STMT_COST
-#define TARG_VEC_STMT_COST 1
-#endif
-
-/* Cost of vector to scalar operation. */
-#ifndef TARG_VEC_TO_SCALAR_COST
-#define TARG_VEC_TO_SCALAR_COST 1
-#endif
-
-/* Cost of scalar to vector operation. */
-#ifndef TARG_SCALAR_TO_VEC_COST
-#define TARG_SCALAR_TO_VEC_COST 1
-#endif
-
-/* Cost of aligned vector load. */
-#ifndef TARG_VEC_LOAD_COST
-#define TARG_VEC_LOAD_COST 1
-#endif
-
-/* Cost of misaligned vector load. */
-#ifndef TARG_VEC_UNALIGNED_LOAD_COST
-#define TARG_VEC_UNALIGNED_LOAD_COST 2
-#endif
-
-/* Cost of vector store. */
-#ifndef TARG_VEC_STORE_COST
-#define TARG_VEC_STORE_COST 1
-#endif
-
-/* Cost of vector permutation. */
-#ifndef TARG_VEC_PERMUTE_COST
-#define TARG_VEC_PERMUTE_COST 1
-#endif
+#define VECT_MAX_COST 1000
/* The maximum number of intermediate steps required in multi-step type
conversion. */
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)
{
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);
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)
{
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)
{
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)
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)
STMT_VINFO_OUTSIDE_OF_LOOP_COST (stmt_info) = cost;
}
+/* Return pow2 (X). */
+
static inline int
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)
{
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_analyze_stmt (gimple, bool *, slp_tree);
extern bool vectorizable_condition (gimple, gimple_stmt_iterator *, gimple *,
tree, int);
+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 *);
/* 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,
- int *);
+ int *, bool *);
extern bool vect_enhance_data_refs_alignment (loop_vec_info);
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 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_iteraion_cost (loop_vec_info);
/* In tree-vect-slp.c. */
extern void vect_free_slp_instance (slp_instance);
extern bool vect_analyze_slp (loop_vec_info, bb_vec_info);
extern void 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) **,
+extern void vect_get_slp_defs (tree, tree, slp_tree, VEC (tree,heap) **,
VEC (tree,heap) **, int);
extern LOC find_bb_location (basic_block);
extern bb_vec_info vect_slp_analyze_bb (basic_block);
/* 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 */