This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH][RFC] C++-style iterators for FOR_EACH_IMM_USE_STMT
On Tue, 29 Oct 2019, Oleg Endo wrote:
> On Tue, 2019-10-29 at 11:26 +0100, Richard Biener wrote:
> > While I converted other iterators requiring special BREAK_FROM_XYZ
> > a few years ago FOR_EACH_IMM_USE_STMT is remaining. I've pondered
> > a bit but cannot arrive at a "nice" solution here with just one
> > iterator as the macros happen to use. For reference, the macro use
> > is
> >
> > imm_use_iterator iter;
> > gimple *use_stmt;
> > FOR_EACH_IMM_USE_STMT (use_stmt, iter, name)
> > {
> > use_operand_p use_p;
> > FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
> > ;
> > }
> >
> > which expands to (w/o macros)
> >
> > imm_use_iterator iter;
> > for (gimple *use_stmt = first_imm_use_stmt (&iter, name);
> > !end_imm_use_stmt_p (&iter);
> > use_stmt = nest_imm_use_stmt (&iter))
> > for (use_operand_p use_p = first_imm_use_on_stmt (&iter);
> > !end_imm_use_on_stmt_p (&iter);
> > use_p = next_imm_use_on_stmt (&iter))
> > ;
> >
> > and my foolish C++ attempt results in
> >
> > for (imm_use_stmt_iter it = SSAVAR; !it.end_p (); ++it)
> > for (imm_use_stmt_iter::use_on_stmt it2 = it; !it2.end_p ();
> > ++it2)
> > ;
> >
> > with *it providing the gimple * USE_STMT and *it2 the use_operand_p.
> > The complication here is to map the two-level iteration to "the C++
> > way".
> > Are there any STL examples mimicing this? Of course with C++11 we
> > could
> > do
> >
> > for (imm_use_stmt_iter it = SSAVAR; !it.end_p (); ++it)
> > for (auto it2 = it.first_use_on_stmt (); !it2.end_p (); ++it2)
> > ;
> >
> > but that's not much nicer either.
>
> Is there a way to put it in such a way that the iterators follow
> standard concepts for iterators? It would increase chances of it
> becoming nicer by utilizing range based for loops.
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].
;)
But yeah, range-based for looks like a nice possibility for most
of our IL iteration besides this special one. Guess nobody
thought of "multi-level" iteration (and yes, we sometimes terminate
the inner loop but continue the outer, so flattening the iteration
isn't a solution here).
Richard.