[PATCH][RFC] C++-style iterators for FOR_EACH_IMM_USE_STMT
Richard Biener
rguenther@suse.de
Mon Nov 4 08:37:00 GMT 2019
On Sun, 3 Nov 2019, Oleg Endo wrote:
> On Wed, 2019-10-30 at 10:27 +0100, Richard Biener wrote:
> >
> > Hmm, not sure - I'd like to write
> >
> > for (gimple *use_stmt : imm_stmt_uses (SSAVAR))
> > for (use_operand_p use_p : <need to refer to the iterator object
> > from
> > above>)
> > ...
> >
> > I don't see how that's possible. It would need to be "awkward" like
> >
> > for (auto it : imm_stmt_uses (SSAVAR))
> > {
> > gimple *use_stmt = *it;
> > for (use_operand_p use_p : it)
> > ...
> > }
> >
> > so the first loops iteration object are the actual iterator and you'd
> > have to do extra indirection to get at the actual stmt you iterated
> > to.
> >
> > So I'd extend C++ (hah) to allow
> >
> > for (gimple *use_stmt : imm_stmt_uses (SSAVAR))
> > for (use_operand_p use_p : auto)
> > ...
> >
> > where 'auto' magically selects the next iterator object in scope
> > [that matches].
> >
> > ;)
>
> Have you applied for a patent yet? :D
>
> How about this one?
>
> for (gimple* use_stmt : imm_stmt_uses (SSAVAR))
> for (use_operand_p use_p : imm_uses_on_stmt (*use_stmt))
>
> ... where helper function "imm_uses_on_stmt" returns a range object
> that offers a begin and end function and its own iterator type.
The issue is that 'use_stmt' isn't enough to compute it. Internally
we just use the same iterator object as for the outer loop but
with range-based for the iterator object isn't accessible. So we'd
need to wrap 'use_stmt' and the iterator object somehow. Closest
would then be
for (auto use_stmt : imm_stmt_uses (SSAVAR))
for (use_operand_p use_p : imm_uses_on_stmt (use_stmt))
...
where use_stmt auto-converts to gimple * and auto hides the
ugliness.
Not very satisfying.
So what we are really doing is iterate over a sorted vector
of use_operand_p sorted after USE_STMT (so uses on the same
stmt come in succession). The inner loop iterates over all
uses on a single USE_STMT and conveniently lets us skip to
the next USE_STMT plus do some common update on a USE_STMT
once we saw all uses on it. Thus..
for (auto_vec<use_operand_p> uses : imm_stmt_uses (SSAVAR))
for (use_operand_p : uses)
...
that is, using a special iterator type for the outer loop iteration
var might be conceptually OK (it's a sub-range of all immediate uses).
So supposedly it's OK to use 'auto' to hide that subrange 'class'
> Another concept that could be interesting are filter iterators.
>
> We used a simplistic re-implementation (c++03) to avoid dragging in
> boost when working on AMS
> https://github.com/erikvarga/gcc/blob/master/gcc/filter_iterator.h
>
> Example uses are
> https://github.com/erikvarga/gcc/blob/master/gcc/ams.h#L845
> https://github.com/erikvarga/gcc/blob/master/gcc/ams.cc#L3715
>
>
> I think there are also some places in RTL where filter iterators could
> be used, e.g. "iterate over all MEMs in an RTL" could be made to look
> something like that:
>
> for (auto&& i : filter_rtl (my_rtl_obj, MEM_P))
> ...
>
>
> Anyway, maybe it can plant some ideas.
:)
Thanks,
Richard.
More information about the Gcc-patches
mailing list