On Oct 28, 2020, Richard Biener <richard.guent...@gmail.com> wrote: >> BTW, any reason why we are not (yet?) using something like: >> >> #define FOR_EACH_IMM_USE_STMT(STMT, ITER, SSAVAR) \ >> for (auto_end_imm_use_stmt_traverse auto_end \ >> ((((STMT) = first_imm_use_stmt (&(ITER), (SSAVAR))), \ >> &(ITER))); \ >> !end_imm_use_stmt_p (&(ITER)); \ >> (void) ((STMT) = next_imm_use_stmt (&(ITER))))
> Just laziness. Or rather last time I remembered this I tried to do it > more fancy via range-for but didn't get very far due to the nested > iteration ... Use a dtor to automatically remove ITER from IMM_USE list in FOR_EACH_IMM_USE_STMT. Regstrapped on x86_64-linux-gnu. Ok to install? for gcc/ChangeLog * ssa-iterators.h (end_imm_use_stmt_traverse): Forward declare. (auto_end_imm_use_stmt_traverse): New struct. (FOR_EACH_IMM_USE_STMT): Use it. --- gcc/ssa-iterators.h | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/gcc/ssa-iterators.h b/gcc/ssa-iterators.h index 98724da14522d..817997aa952d4 100644 --- a/gcc/ssa-iterators.h +++ b/gcc/ssa-iterators.h @@ -77,16 +77,35 @@ struct imm_use_iterator !end_readonly_imm_use_p (&(ITER)); \ (void) ((DEST) = next_readonly_imm_use (&(ITER)))) -/* Use this iterator to visit each stmt which has a use of SSAVAR. */ +/* Forward declare for use in the class below. */ +static inline void end_imm_use_stmt_traverse (imm_use_iterator *); + +/* arrange to automatically call, upon descruction, end_imm_use_stmt_traverse + with a given pointer to imm_use_iterator. */ +struct auto_end_imm_use_stmt_traverse +{ + imm_use_iterator *imm; + auto_end_imm_use_stmt_traverse (imm_use_iterator *imm) + : imm (imm) {} + ~auto_end_imm_use_stmt_traverse () + { end_imm_use_stmt_traverse (imm); } +}; + +/* Use this iterator to visit each stmt which has a use of SSAVAR. The + destructor of the auto_end_imm_use_stmt_traverse object deals with removing + ITER from SSAVAR's IMM_USE list even when leaving the scope early. */ #define FOR_EACH_IMM_USE_STMT(STMT, ITER, SSAVAR) \ - for ((STMT) = first_imm_use_stmt (&(ITER), (SSAVAR)); \ + for (struct auto_end_imm_use_stmt_traverse \ + auto_end_imm_use_stmt_traverse \ + ((((STMT) = first_imm_use_stmt (&(ITER), (SSAVAR))), \ + &(ITER))); \ !end_imm_use_stmt_p (&(ITER)); \ (void) ((STMT) = next_imm_use_stmt (&(ITER)))) -/* Use this to terminate the FOR_EACH_IMM_USE_STMT loop early. Failure to - do so will result in leaving a iterator marker node in the immediate - use list, and nothing good will come from that. */ +/* These used to be needed to exit FOR_EACH_IMM_USE_STMT early, without leaving + ITER behind in the stmt lists. This is now taken care of automatically, but + it doesn't hurt to use the macros for documentation purposes. */ #define BREAK_FROM_IMM_USE_STMT(ITER) \ { \ end_imm_use_stmt_traverse (&(ITER)); \ -- Alexandre Oliva, happy hacker https://FSFLA.org/blogs/lxo/ Free Software Activist GNU Toolchain Engineer Vim, Vi, Voltei pro Emacs -- GNUlius Caesar