_loop_vec_info::_loop_vec_info (class loop *loop_in, vec_info_shared *shared)
: vec_info (vec_info::loop, shared),
loop (loop_in),
- bbs (XCNEWVEC (basic_block, loop->num_nodes)),
num_itersm1 (NULL_TREE),
num_iters (NULL_TREE),
num_iters_unchanged (NULL_TREE),
case of the loop forms we allow, a dfs order of the BBs would the same
as reversed postorder traversal, so we are safe. */
- unsigned int nbbs = dfs_enumerate_from (loop->header, 0, bb_in_loop_p,
- bbs, loop->num_nodes, loop);
+ bbs = XCNEWVEC (basic_block, loop->num_nodes);
+ nbbs = dfs_enumerate_from (loop->header, 0, bb_in_loop_p, bbs,
+ loop->num_nodes, loop);
gcc_assert (nbbs == loop->num_nodes);
for (unsigned int i = 0; i < nbbs; i++)
free (LOOP_VINFO_BBS (epilogue_vinfo));
LOOP_VINFO_BBS (epilogue_vinfo) = epilogue_bbs;
+ LOOP_VINFO_NBBS (epilogue_vinfo) = epilogue->num_nodes;
/* Advance data_reference's with the number of iterations of the previous
loop and its prologue. */
void
vect_determine_precisions (vec_info *vinfo)
{
+ basic_block *bbs = vinfo->bbs;
+ unsigned int nbbs = vinfo->nbbs;
+
DUMP_VECT_SCOPE ("vect_determine_precisions");
- if (loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo))
+ for (unsigned int i = 0; i < nbbs; i++)
{
- class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
- basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
- unsigned int nbbs = loop->num_nodes;
-
- for (unsigned int i = 0; i < nbbs; i++)
+ basic_block bb = bbs[i];
+ for (auto gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- basic_block bb = bbs[i];
- for (auto gsi = gsi_start_phis (bb);
- !gsi_end_p (gsi); gsi_next (&gsi))
- {
- stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi.phi ());
- if (stmt_info)
- vect_determine_mask_precision (vinfo, stmt_info);
- }
- for (auto si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
- if (!is_gimple_debug (gsi_stmt (si)))
- vect_determine_mask_precision
- (vinfo, vinfo->lookup_stmt (gsi_stmt (si)));
+ stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi.phi ());
+ if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
+ vect_determine_mask_precision (vinfo, stmt_info);
}
- for (unsigned int i = 0; i < nbbs; i++)
+ for (auto gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- basic_block bb = bbs[nbbs - i - 1];
- for (gimple_stmt_iterator si = gsi_last_bb (bb);
- !gsi_end_p (si); gsi_prev (&si))
- if (!is_gimple_debug (gsi_stmt (si)))
- vect_determine_stmt_precisions
- (vinfo, vinfo->lookup_stmt (gsi_stmt (si)));
- for (auto gsi = gsi_start_phis (bb);
- !gsi_end_p (gsi); gsi_next (&gsi))
- {
- stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi.phi ());
- if (stmt_info)
- vect_determine_stmt_precisions (vinfo, stmt_info);
- }
+ stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi_stmt (gsi));
+ if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
+ vect_determine_mask_precision (vinfo, stmt_info);
}
}
- else
+ for (unsigned int i = 0; i < nbbs; i++)
{
- bb_vec_info bb_vinfo = as_a <bb_vec_info> (vinfo);
- for (unsigned i = 0; i < bb_vinfo->bbs.length (); ++i)
+ basic_block bb = bbs[nbbs - i - 1];
+ for (auto gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
{
- basic_block bb = bb_vinfo->bbs[i];
- for (auto gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
- {
- stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi.phi ());
- if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
- vect_determine_mask_precision (vinfo, stmt_info);
- }
- for (auto gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
- {
- stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi_stmt (gsi));
- if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
- vect_determine_mask_precision (vinfo, stmt_info);
- }
+ stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi_stmt (gsi));
+ if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
+ vect_determine_stmt_precisions (vinfo, stmt_info);
}
- for (int i = bb_vinfo->bbs.length () - 1; i != -1; --i)
+ for (auto gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- for (gimple_stmt_iterator gsi = gsi_last_bb (bb_vinfo->bbs[i]);
- !gsi_end_p (gsi); gsi_prev (&gsi))
- {
- stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi_stmt (gsi));
- if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
- vect_determine_stmt_precisions (vinfo, stmt_info);
- }
- for (auto gsi = gsi_start_phis (bb_vinfo->bbs[i]);
- !gsi_end_p (gsi); gsi_next (&gsi))
- {
- stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi.phi ());
- if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
- vect_determine_stmt_precisions (vinfo, stmt_info);
- }
+ stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi.phi ());
+ if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
+ vect_determine_stmt_precisions (vinfo, stmt_info);
}
}
}
void
vect_pattern_recog (vec_info *vinfo)
{
- class loop *loop;
- basic_block *bbs;
- unsigned int nbbs;
- gimple_stmt_iterator si;
- unsigned int i, j;
+ basic_block *bbs = vinfo->bbs;
+ unsigned int nbbs = vinfo->nbbs;
vect_determine_precisions (vinfo);
DUMP_VECT_SCOPE ("vect_pattern_recog");
- if (loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo))
+ /* Scan through the stmts in the region, applying the pattern recognition
+ functions starting at each stmt visited. */
+ for (unsigned i = 0; i < nbbs; i++)
{
- loop = LOOP_VINFO_LOOP (loop_vinfo);
- bbs = LOOP_VINFO_BBS (loop_vinfo);
- nbbs = loop->num_nodes;
+ basic_block bb = bbs[i];
- /* Scan through the loop stmts, applying the pattern recognition
- functions starting at each stmt visited: */
- for (i = 0; i < nbbs; i++)
+ for (auto si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{
- basic_block bb = bbs[i];
- for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
- {
- if (is_gimple_debug (gsi_stmt (si)))
- continue;
- stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi_stmt (si));
- /* Scan over all generic vect_recog_xxx_pattern functions. */
- for (j = 0; j < NUM_PATTERNS; j++)
- vect_pattern_recog_1 (vinfo, &vect_vect_recog_func_ptrs[j],
- stmt_info);
- }
+ stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi_stmt (si));
+
+ if (!stmt_info || !STMT_VINFO_VECTORIZABLE (stmt_info))
+ continue;
+
+ /* Scan over all generic vect_recog_xxx_pattern functions. */
+ for (unsigned j = 0; j < NUM_PATTERNS; j++)
+ vect_pattern_recog_1 (vinfo, &vect_vect_recog_func_ptrs[j],
+ stmt_info);
}
}
- else
- {
- bb_vec_info bb_vinfo = as_a <bb_vec_info> (vinfo);
- for (unsigned i = 0; i < bb_vinfo->bbs.length (); ++i)
- for (gimple_stmt_iterator gsi = gsi_start_bb (bb_vinfo->bbs[i]);
- !gsi_end_p (gsi); gsi_next (&gsi))
- {
- stmt_vec_info stmt_info = bb_vinfo->lookup_stmt (gsi_stmt (gsi));
- if (!stmt_info || !STMT_VINFO_VECTORIZABLE (stmt_info))
- continue;
-
- /* Scan over all generic vect_recog_xxx_pattern functions. */
- for (j = 0; j < NUM_PATTERNS; j++)
- vect_pattern_recog_1 (vinfo,
- &vect_vect_recog_func_ptrs[j], stmt_info);
- }
- }
/* After this no more add_stmt calls are allowed. */
vinfo->stmt_vec_info_ro = true;
&& is_a <bb_vec_info> (vinfo)
&& TREE_CODE (oprnd) == SSA_NAME
&& !SSA_NAME_IS_DEFAULT_DEF (oprnd)
- && !dominated_by_p (CDI_DOMINATORS,
- as_a <bb_vec_info> (vinfo)->bbs[0],
+ && !dominated_by_p (CDI_DOMINATORS, vinfo->bbs[0],
gimple_bb (SSA_NAME_DEF_STMT (oprnd))))
{
if (dump_enabled_p ())
_bb_vec_info::_bb_vec_info (vec<basic_block> _bbs, vec_info_shared *shared)
: vec_info (vec_info::bb, shared),
- bbs (_bbs),
roots (vNULL)
{
- for (unsigned i = 0; i < bbs.length (); ++i)
+ /* The region we are operating on. bbs[0] is the entry, excluding
+ its PHI nodes. In the future we might want to track an explicit
+ entry edge to cover bbs[0] PHI nodes and have a region entry
+ insert location. */
+ bbs = _bbs.address ();
+ nbbs = _bbs.length ();
+
+ for (unsigned i = 0; i < nbbs; ++i)
{
if (i != 0)
for (gphi_iterator si = gsi_start_phis (bbs[i]); !gsi_end_p (si);
_bb_vec_info::~_bb_vec_info ()
{
/* Reset region marker. */
- for (unsigned i = 0; i < bbs.length (); ++i)
+ for (unsigned i = 0; i < nbbs; ++i)
{
if (i != 0)
for (gphi_iterator si = gsi_start_phis (bbs[i]); !gsi_end_p (si);
static void
vect_slp_check_for_roots (bb_vec_info bb_vinfo)
{
- for (unsigned i = 0; i < bb_vinfo->bbs.length (); ++i)
+ for (unsigned i = 0; i < bb_vinfo->nbbs; ++i)
for (gimple_stmt_iterator gsi = gsi_start_bb (bb_vinfo->bbs[i]);
!gsi_end_p (gsi); gsi_next (&gsi))
{
we vectorized all if-converted code. */
if ((!profitable_subgraphs.is_empty () || force_clear) && orig_loop)
{
- gcc_assert (bb_vinfo->bbs.length () == 1);
+ gcc_assert (bb_vinfo->nbbs == 1);
for (gimple_stmt_iterator gsi = gsi_start_bb (bb_vinfo->bbs[0]);
!gsi_end_p (gsi); gsi_next (&gsi))
{
if (!last_stmt)
{
gcc_assert (seen_vector_def);
- si = gsi_after_labels (as_a <bb_vec_info> (vinfo)->bbs[0]);
+ si = gsi_after_labels (vinfo->bbs[0]);
}
else if (is_ctrl_altering_stmt (last_stmt))
{
/* We split regions to vectorize at control altering stmts
with a definition so this must be an external which
we can insert at the start of the region. */
- si = gsi_after_labels (as_a <bb_vec_info> (vinfo)->bbs[0]);
+ si = gsi_after_labels (vinfo->bbs[0]);
}
else if (is_a <bb_vec_info> (vinfo)
&& gimple_bb (last_stmt) != gimple_bb (stmt_info->stmt)
made any decisions about which vector modes to use. */
machine_mode vector_mode;
+ /* The basic blocks in the vectorization region. For _loop_vec_info,
+ the memory is internally managed, while for _bb_vec_info, it points
+ to element space of an external auto_vec<>. This inconsistency is
+ not a good class design pattern. TODO: improve it with an unified
+ auto_vec<> whose lifetime is confined to vec_info object. */
+ basic_block *bbs;
+
+ /* The count of the basic blocks in the vectorization region. */
+ unsigned int nbbs;
+
private:
stmt_vec_info new_stmt_vec_info (gimple *stmt);
void set_vinfo_for_stmt (gimple *, stmt_vec_info, bool = true);
/* The loop to which this info struct refers to. */
class loop *loop;
- /* The loop basic blocks. */
- basic_block *bbs;
-
/* Number of latch executions. */
tree num_itersm1;
/* Number of iterations. */
#define LOOP_VINFO_EPILOGUE_IV_EXIT(L) (L)->vec_epilogue_loop_iv_exit
#define LOOP_VINFO_SCALAR_IV_EXIT(L) (L)->scalar_loop_iv_exit
#define LOOP_VINFO_BBS(L) (L)->bbs
+#define LOOP_VINFO_NBBS(L) (L)->nbbs
#define LOOP_VINFO_NITERSM1(L) (L)->num_itersm1
#define LOOP_VINFO_NITERS(L) (L)->num_iters
/* Since LOOP_VINFO_NITERS and LOOP_VINFO_NITERSM1 can change after
_bb_vec_info (vec<basic_block> bbs, vec_info_shared *);
~_bb_vec_info ();
- /* The region we are operating on. bbs[0] is the entry, excluding
- its PHI nodes. In the future we might want to track an explicit
- 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
+#define BB_VINFO_BBS(B) (B)->bbs
+#define BB_VINFO_NBBS(B) (B)->nbbs
#define BB_VINFO_GROUPED_STORES(B) (B)->grouped_stores
#define BB_VINFO_SLP_INSTANCES(B) (B)->slp_instances
#define BB_VINFO_DATAREFS(B) (B)->shared->datarefs