diff options
Diffstat (limited to 'gcc/tree-vectorizer.h')
-rw-r--r-- | gcc/tree-vectorizer.h | 139 |
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 */ |