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.