Martin Liška <[email protected]> writes:
> On 6/16/20 10:50 AM, Richard Sandiford wrote:
>> Martin Liška <[email protected]> writes:
>>>> Also, one minor formatting nit, sorry: the other functions instead
>>>> indent the “{” block by the same amount as the function prototype,
>>>> which seems more consistent with the usual out-of-class formatting.
>>>
>>> Hope I fixed that.
>>
>> Sorry, I meant the other functions were IMO formatted correctly, with the
>> “{” directly under the function name. It looks like the new patch instead
>> indents all “{” by two spaces relative to the function name or “struct”
>> keyword. I.e. IMO:
>>
>> struct const_iterator
>> {
>> };
>>
>> seems better than:
>>
>> struct const_iterator
>> {
>> };
>>
>> and:
>>
>> const const_iterator &
>> operator++ ()
>> {
>> }
>>
>> seems better than:
>>
>> const const_iterator &
>> operator++ ()
>> {
>> }
>>
>> This makes the formatting consistent with definitions in column 0.
>>
>>> About rbiener's comment, I wrapper the iterators with
>>> bb_vinfo::region_stmts..
>>
>> Sorry for dragging this on longer, but…
>>
>>> @@ -5120,20 +5120,14 @@ vect_determine_precisions (vec_info *vinfo)
>>> else
>>> {
>>> bb_vec_info bb_vinfo = as_a <bb_vec_info> (vinfo);
>>> - gimple_stmt_iterator si = bb_vinfo->region_end;
>>> - gimple *stmt;
>>> - do
>>> + for ( _bb_vec_info::reverse_iterator it =
>>> bb_vinfo->region_stmts.rbegin ();
>>> + it != bb_vinfo->region_stmts.rend (); ++it)
>>> {
>>> - if (!gsi_stmt (si))
>>> - si = gsi_last_bb (bb_vinfo->bb);
>>> - else
>>> - gsi_prev (&si);
>>> - stmt = gsi_stmt (si);
>>> + gimple *stmt = *it;
>>> stmt_vec_info stmt_info = vinfo->lookup_stmt (stmt);
>>> if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
>>> vect_determine_stmt_precisions (vinfo, stmt_info);
>>> }
>>> - while (stmt != gsi_stmt (bb_vinfo->region_begin));
>>> }
>>> }
>>
>> I think this should be a similar style, i.e.
>>
>> for (gimple *stmt : bb_vinfo->reverse_region_stmts ())
>>
>> rather than using iterators directly.
>>
>>> @@ -5492,10 +5486,8 @@ vect_pattern_recog (vec_info *vinfo)
>>> else
>>> {
>>> bb_vec_info bb_vinfo = as_a <bb_vec_info> (vinfo);
>>> - for (si = bb_vinfo->region_begin;
>>> - gsi_stmt (si) != gsi_stmt (bb_vinfo->region_end); gsi_next (&si))
>>> + for (gimple *stmt : bb_vinfo->region_stmts)
>>> {
>>> - gimple *stmt = gsi_stmt (si);
>>> stmt_vec_info stmt_info = bb_vinfo->lookup_stmt (stmt);
>>> if (!stmt_info || !STMT_VINFO_VECTORIZABLE (stmt_info))
>>> continue;
>>> diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
>>> index 303410c2fc4..f4809c2207d 100644
>>> --- a/gcc/tree-vect-slp.c
>>> +++ b/gcc/tree-vect-slp.c
>>> @@ -2546,20 +2546,15 @@ vect_detect_hybrid_slp (loop_vec_info loop_vinfo)
>>> /* Initialize a bb_vec_info struct for the statements between
>>> REGION_BEGIN_IN (inclusive) and REGION_END_IN (exclusive). */
>>>
>>> -_bb_vec_info::_bb_vec_info (gimple_stmt_iterator region_begin_in,
>>> - gimple_stmt_iterator region_end_in,
>>> +_bb_vec_info::_bb_vec_info (gimple_stmt_iterator region_begin,
>>> + gimple_stmt_iterator region_end,
>>> vec_info_shared *shared)
>>> : vec_info (vec_info::bb, init_cost (NULL), shared),
>>> - bb (gsi_bb (region_begin_in)),
>>> - region_begin (region_begin_in),
>>> - region_end (region_end_in)
>>> + bb (gsi_bb (region_begin)),
>>> + region_stmts (region_begin, region_end)
>>> {
>>> - gimple_stmt_iterator gsi;
>>> -
>>> - for (gsi = region_begin; gsi_stmt (gsi) != gsi_stmt (region_end);
>>> - gsi_next (&gsi))
>>> + for (gimple *stmt : this->region_stmts)
>>> {
>>> - gimple *stmt = gsi_stmt (gsi);
>>> gimple_set_uid (stmt, 0);
>>> if (is_gimple_debug (stmt))
>>> continue;
>>> @@ -2575,10 +2570,9 @@ _bb_vec_info::_bb_vec_info (gimple_stmt_iterator
>>> region_begin_in,
>>>
>>> _bb_vec_info::~_bb_vec_info ()
>>> {
>>> - for (gimple_stmt_iterator si = region_begin;
>>> - gsi_stmt (si) != gsi_stmt (region_end); gsi_next (&si))
>>> + for (gimple *stmt : this->region_stmts)
>>> /* Reset region marker. */
>>> - gimple_set_uid (gsi_stmt (si), -1);
>>> + gimple_set_uid (stmt, -1);
>>>
>>> bb->aux = NULL;
>>> }
>>> @@ -3012,16 +3006,13 @@ vect_bb_vectorization_profitable_p (bb_vec_info
>>> bb_vinfo)
>>> static void
>>> vect_slp_check_for_constructors (bb_vec_info bb_vinfo)
>>> {
>>> - gimple_stmt_iterator gsi;
>>> -
>>> - for (gsi = bb_vinfo->region_begin;
>>> - gsi_stmt (gsi) != gsi_stmt (bb_vinfo->region_end); gsi_next (&gsi))
>>> + for (gimple *stmt : bb_vinfo->region_stmts)
>>> {
>>> - gassign *stmt = dyn_cast <gassign *> (gsi_stmt (gsi));
>>> - if (!stmt || gimple_assign_rhs_code (stmt) != CONSTRUCTOR)
>>> + gassign *assign = dyn_cast <gassign *> (stmt);
>>> + if (!assign || gimple_assign_rhs_code (assign) != CONSTRUCTOR)
>>> continue;
>>>
>>> - tree rhs = gimple_assign_rhs1 (stmt);
>>> + tree rhs = gimple_assign_rhs1 (assign);
>>> if (!VECTOR_TYPE_P (TREE_TYPE (rhs))
>>> || maybe_ne (TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs)),
>>> CONSTRUCTOR_NELTS (rhs))
>>> @@ -3029,7 +3020,7 @@ vect_slp_check_for_constructors (bb_vec_info bb_vinfo)
>>> || uniform_vector_p (rhs))
>>> continue;
>>>
>>> - stmt_vec_info stmt_info = bb_vinfo->lookup_stmt (stmt);
>>> + stmt_vec_info stmt_info = bb_vinfo->lookup_stmt (assign);
>>> BB_VINFO_GROUPED_STORES (bb_vinfo).safe_push (stmt_info);
>>> }
>>> }
>>> diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
>>> index 6c830ad09f4..c94817e6af6 100644
>>> --- a/gcc/tree-vectorizer.h
>>> +++ b/gcc/tree-vectorizer.h
>>> @@ -787,12 +787,92 @@ loop_vec_info_for_loop (class loop *loop)
>>> typedef class _bb_vec_info : public vec_info
>>> {
>>> public:
>>> + struct const_iterator
>>> + {
>>
>> “{” should be directly under “struct”.
>>
>>> + const_iterator (gimple_stmt_iterator _gsi) : gsi (_gsi) {}
>>> +
>>> + const const_iterator &
>>> + operator++ ()
>>> + {
>>
>> “{” should be directly under “operator++”. Same for the other structs
>> and functions.
>>
>>> + gsi_next (&gsi); return *this;
>>> + }
>>> +
>>> + gimple *operator* () const { return gsi_stmt (gsi); }
>>> +
>>> + bool
>>> + operator== (const const_iterator& other) const
>>> + {
>>> + return gsi_stmt (gsi) == gsi_stmt (other.gsi);
>>> + }
>>> +
>>> + bool
>>> + operator!= (const const_iterator& other) const
>>> + {
>>> + return !(*this == other);
>>> + }
>>> +
>>> + gimple_stmt_iterator gsi;
>>> + };
>>> +
>>> + struct reverse_iterator
>>
>> This should be a const_reverse_iterator.
>>
>>> + {
>>> + reverse_iterator (gimple_stmt_iterator _gsi) : gsi (_gsi) {}
>>> +
>>> + const reverse_iterator &
>>> + operator++ ()
>>> + {
>>> + gsi_prev (&gsi); return *this;
>>> + }
>>> +
>>> + gimple *operator* () const { return gsi_stmt (gsi); }
>>> +
>>> + bool
>>> + operator== (const reverse_iterator& other) const
>>> + {
>>> + return gsi_stmt (gsi) == gsi_stmt (other.gsi);
>>> + }
>>> +
>>> + bool
>>> + operator!= (const reverse_iterator& other) const
>>> + {
>>> + return !(*this == other);
>>> + }
>>> +
>>> + gimple_stmt_iterator gsi;
>>> + };
>>> +
>>> + struct stmt_iterator
>>> + {
>>> + stmt_iterator (gimple_stmt_iterator region_begin,
>>> + gimple_stmt_iterator region_end)
>>> + : m_region_begin (region_begin), m_region_end (region_end) {}
>>> +
>>> + gimple_stmt_iterator region_begin () { return m_region_begin; }
>>> +
>>> + const_iterator begin () const { return const_iterator
>>> (m_region_begin); }
>>> + const_iterator end () const { return const_iterator (m_region_end); }
>>> +
>>> + gimple_stmt_iterator m_region_begin;
>>> + gimple_stmt_iterator m_region_end;
>>> +
>>> + reverse_iterator rbegin () const
>>> + {
>>> + reverse_iterator it = reverse_iterator (m_region_end);
>>> + if (*it == NULL)
>>> + return reverse_iterator (gsi_last_bb (m_region_end.bb));
>>> + else
>>> + return ++it;
>>> + }
>>> +
>>> + reverse_iterator rend () const { return reverse_iterator
>>> (m_region_begin); }
>>> + };
>
> Thank you for the review. I'm skipping for now the renaming and formatting
> changes which
> I'll do later.
>
>>
>> I think for this we should have a template class for begin/end iterator
>> pairs, probably in coretypes.h. We could call it “iterator_pair” or
>> something. Then “region_stmts” would return (see below) a:
>>
>> iterator_pair<const_iterator>
>>
>> and “reverse_region_stmts” would return:
>>
>> iterator_pair<const_reverse_iterator>
>
> Hmm, sounds like a nice abstraction but I see 2 problems with that:
>
> 1) How can I define a constructor of the iterator_pair when I need something
> like:
> iterator_pair<const_iterator> (region_begin, region_end)?
Not sure if I'm answering the right question, sorry, but I meant
something along the lines of:
template<typename T>
struct iterator_pair
{
public:
iterator_pair (const T &begin, const T &end)
: m_begin (begin), m_end (end) {}
T begin () const { return m_begin; }
T end () const { return m_end; }
private:
T m_begin;
T m_end;
};
> 2) rbegin function is more complex than begin function:
>
> reverse_iterator rbegin () const
> {
> reverse_iterator it = reverse_iterator (m_region_end);
> if (*it == NULL)
> return reverse_iterator (gsi_last_bb (m_region_end.bb));
> else
> return ++it;
> }
>
> const_iterator begin () const { return const_iterator
> (m_region_begin); }
>
> How can we abstract that?
With the change above, we'd replace “rbegin” and “rend”
with a “reverse_region_stmts” function that returns an
“iterator_pair<const_reverse_iterator>”. Its “begin” iterator
would have the value that “rbegin” calculates above and its “end”
iterator would have the same value as the current patch's “rend”.
Thanks,
Richard