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.