aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vectorizer.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-vectorizer.h')
-rw-r--r--gcc/tree-vectorizer.h139
1 files changed, 135 insertions, 4 deletions
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index b56073c..66e6b50 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -26,6 +26,7 @@ typedef class _stmt_vec_info *stmt_vec_info;
#include "tree-data-ref.h"
#include "tree-hash-traits.h"
#include "target.h"
+#include "internal-fn.h"
/* Used for naming of new temporaries. */
@@ -114,6 +115,8 @@ typedef hash_map<tree_operand_hash,
SLP
************************************************************************/
typedef struct _slp_tree *slp_tree;
+typedef vec<std::pair<unsigned, unsigned> > lane_permutation_t;
+typedef vec<unsigned> load_permutation_t;
/* A computation tree of an SLP instance. Each node corresponds to a group of
stmts to be packed in a SIMD stmt. */
@@ -134,11 +137,11 @@ struct _slp_tree {
/* Load permutation relative to the stores, NULL if there is no
permutation. */
- vec<unsigned> load_permutation;
+ load_permutation_t load_permutation;
/* Lane permutation of the operands scalar lanes encoded as pairs
of { operand number, lane number }. The number of elements
denotes the number of output lanes. */
- vec<std::pair<unsigned, unsigned> > lane_permutation;
+ lane_permutation_t lane_permutation;
tree vectype;
/* Vectorized stmt/s. */
@@ -163,8 +166,27 @@ struct _slp_tree {
enum tree_code code;
int vertex;
+
+ /* Allocate from slp_tree_pool. */
+ static void *operator new (size_t);
+
+ /* Return memory to slp_tree_pool. */
+ static void operator delete (void *, size_t);
+
+ /* Linked list of nodes to release when we free the slp_tree_pool. */
+ slp_tree next_node;
+ slp_tree prev_node;
};
+/* The enum describes the type of operations that an SLP instance
+ can perform. */
+
+enum slp_instance_kind {
+ slp_inst_kind_store,
+ slp_inst_kind_reduc_group,
+ slp_inst_kind_reduc_chain,
+ slp_inst_kind_ctor
+};
/* SLP instance is a sequence of stmts in a loop that can be packed into
SIMD stmts. */
@@ -193,6 +215,9 @@ public:
entries into the same subgraph, including itself. */
vec<_slp_instance *> subgraph_entries;
+ /* The type of operation the SLP instance is performing. */
+ slp_instance_kind kind;
+
dump_user_location_t location () const;
} *slp_instance;
@@ -202,6 +227,7 @@ public:
#define SLP_INSTANCE_UNROLLING_FACTOR(S) (S)->unrolling_factor
#define SLP_INSTANCE_LOADS(S) (S)->loads
#define SLP_INSTANCE_ROOT_STMT(S) (S)->root_stmt
+#define SLP_INSTANCE_KIND(S) (S)->kind
#define SLP_TREE_CHILDREN(S) (S)->children
#define SLP_TREE_SCALAR_STMTS(S) (S)->stmts
@@ -339,6 +365,7 @@ public:
~vec_info ();
stmt_vec_info add_stmt (gimple *);
+ stmt_vec_info add_pattern_stmt (gimple *, stmt_vec_info);
stmt_vec_info lookup_stmt (gimple *);
stmt_vec_info lookup_def (tree);
stmt_vec_info lookup_single_use (tree);
@@ -384,7 +411,7 @@ public:
private:
stmt_vec_info new_stmt_vec_info (gimple *stmt);
- void set_vinfo_for_stmt (gimple *, stmt_vec_info);
+ void set_vinfo_for_stmt (gimple *, stmt_vec_info, bool = true);
void free_stmt_vec_infos ();
void free_stmt_vec_info (stmt_vec_info);
};
@@ -826,6 +853,16 @@ loop_vec_info_for_loop (class loop *loop)
return (loop_vec_info) loop->aux;
}
+struct slp_root
+{
+ slp_root (slp_instance_kind kind_, vec<stmt_vec_info> stmts_,
+ stmt_vec_info root_)
+ : kind(kind_), stmts(stmts_), root(root_) {}
+ slp_instance_kind kind;
+ vec<stmt_vec_info> stmts;
+ stmt_vec_info root;
+};
+
typedef class _bb_vec_info : public vec_info
{
public:
@@ -837,6 +874,8 @@ public:
entry edge to cover bbs[0] PHI nodes and have a region entry
insert location. */
vec<basic_block> bbs;
+
+ vec<slp_root> roots;
} *bb_vec_info;
#define BB_VINFO_BB(B) (B)->bb
@@ -872,6 +911,7 @@ enum stmt_vec_info_type {
type_conversion_vec_info_type,
cycle_phi_info_type,
lc_phi_info_type,
+ phi_info_type,
loop_exit_ctrl_vec_info_type
};
@@ -1930,6 +1970,8 @@ extern bool vect_transform_cycle_phi (loop_vec_info, stmt_vec_info,
slp_tree, slp_instance);
extern bool vectorizable_lc_phi (loop_vec_info, stmt_vec_info,
gimple **, slp_tree);
+extern bool vectorizable_phi (vec_info *, stmt_vec_info, gimple **, slp_tree,
+ stmt_vector_for_cost *);
extern bool vect_worthwhile_without_simd_p (vec_info *, tree_code);
extern int vect_get_known_peeling_cost (loop_vec_info, int, int *,
stmt_vector_for_cost *,
@@ -1938,16 +1980,20 @@ extern int vect_get_known_peeling_cost (loop_vec_info, int, int *,
extern tree cse_and_gimplify_to_preheader (loop_vec_info, tree);
/* In tree-vect-slp.c. */
+extern void vect_slp_init (void);
+extern void vect_slp_fini (void);
extern void vect_free_slp_instance (slp_instance);
extern bool vect_transform_slp_perm_load (vec_info *, slp_tree, vec<tree>,
gimple_stmt_iterator *, poly_uint64,
- bool, unsigned *);
+ bool, unsigned *,
+ unsigned * = nullptr);
extern bool vect_slp_analyze_operations (vec_info *);
extern void vect_schedule_slp (vec_info *, vec<slp_instance>);
extern opt_result vect_analyze_slp (vec_info *, unsigned);
extern bool vect_make_slp_decision (loop_vec_info);
extern void vect_detect_hybrid_slp (loop_vec_info);
extern void vect_optimize_slp (vec_info *);
+extern void vect_gather_slp_loads (vec_info *);
extern void vect_get_slp_defs (slp_tree, vec<tree> *);
extern void vect_get_slp_defs (vec_info *, slp_tree, vec<vec<tree> > *,
unsigned n = -1U);
@@ -1963,8 +2009,13 @@ extern void duplicate_and_interleave (vec_info *, gimple_seq *, tree,
vec<tree>, unsigned int, vec<tree> &);
extern int vect_get_place_in_interleaving_chain (stmt_vec_info, stmt_vec_info);
extern bool vect_update_shared_vectype (stmt_vec_info, tree);
+extern slp_tree vect_create_new_slp_node (unsigned, tree_code);
+extern void vect_free_slp_tree (slp_tree);
/* In tree-vect-patterns.c. */
+extern void
+vect_mark_pattern_stmts (vec_info *, stmt_vec_info, gimple *, tree);
+
/* Pattern recognition functions.
Additional pattern recognition functions can (and will) be added
in the future. */
@@ -1976,4 +2027,84 @@ void vect_free_loop_info_assumptions (class loop *);
gimple *vect_loop_vectorized_call (class loop *, gcond **cond = NULL);
bool vect_stmt_dominates_stmt_p (gimple *, gimple *);
+/* SLP Pattern matcher types, tree-vect-slp-patterns.c. */
+
+/* Forward declaration of possible two operands operation that can be matched
+ by the complex numbers pattern matchers. */
+enum _complex_operation : unsigned;
+
+/* All possible load permute values that could result from the partial data-flow
+ analysis. */
+typedef enum _complex_perm_kinds {
+ PERM_UNKNOWN,
+ PERM_EVENODD,
+ PERM_ODDEVEN,
+ PERM_ODDODD,
+ PERM_EVENEVEN,
+ /* Can be combined with any other PERM values. */
+ PERM_TOP
+} complex_perm_kinds_t;
+
+/* A pair with a load permute and a corresponding complex_perm_kind which gives
+ information about the load it represents. */
+typedef std::pair<complex_perm_kinds_t, load_permutation_t>
+ complex_load_perm_t;
+
+/* Cache from nodes to the load permutation they represent. */
+typedef hash_map <slp_tree, complex_load_perm_t>
+ slp_tree_to_load_perm_map_t;
+
+/* Vector pattern matcher base class. All SLP pattern matchers must inherit
+ from this type. */
+
+class vect_pattern
+{
+ protected:
+ /* The number of arguments that the IFN requires. */
+ unsigned m_num_args;
+
+ /* The internal function that will be used when a pattern is created. */
+ internal_fn m_ifn;
+
+ /* The current node being inspected. */
+ slp_tree *m_node;
+
+ /* The list of operands to be the children for the node produced when the
+ internal function is created. */
+ vec<slp_tree> m_ops;
+
+ /* Default constructor where NODE is the root of the tree to inspect. */
+ vect_pattern (slp_tree *node, vec<slp_tree> *m_ops, internal_fn ifn)
+ {
+ this->m_ifn = ifn;
+ this->m_node = node;
+ this->m_ops.create (0);
+ this->m_ops.safe_splice (*m_ops);
+ }
+
+ public:
+
+ /* Create a new instance of the pattern matcher class of the given type. */
+ static vect_pattern* recognize (slp_tree_to_load_perm_map_t *, slp_tree *);
+
+ /* Build the pattern from the data collected so far. */
+ virtual void build (vec_info *) = 0;
+
+ /* Default destructor. */
+ virtual ~vect_pattern ()
+ {
+ this->m_ops.release ();
+ }
+};
+
+/* Function pointer to create a new pattern matcher from a generic type. */
+typedef vect_pattern* (*vect_pattern_decl_t) (slp_tree_to_load_perm_map_t *,
+ slp_tree *);
+
+/* List of supported pattern matchers. */
+extern vect_pattern_decl_t slp_patterns[];
+
+/* Number of supported pattern matchers. */
+extern size_t num__slp_patterns;
+
#endif /* GCC_TREE_VECTORIZER_H */