On 11/5/25 04:55, Richard Biener wrote:
This clarifies the constraints of the immediate use iterators,
documenting how exactly stmts and their immediate uses might be
altered during it.
I have bootstrapped and tested the series on x86_64-unknown-linux-gnu,
the prerequesites have been pushed.
Does this look OK? If so I'll go ahead with this (and expect some
fallout, but there's now the tools to fixup reasonably easy).
Thanks,
Richard.
* doc/tree-ssa.texi: Update immediate use iterator
documentation.
* ssa-iterators.h: Likewise.
---
gcc/doc/tree-ssa.texi | 33 ++++++++++++++++++++++++++++-----
gcc/ssa-iterators.h | 8 ++++----
2 files changed, 32 insertions(+), 9 deletions(-)
diff --git a/gcc/doc/tree-ssa.texi b/gcc/doc/tree-ssa.texi
index 25aa006d48e..670571e1cb0 100644
--- a/gcc/doc/tree-ssa.texi
+++ b/gcc/doc/tree-ssa.texi
@@ -383,11 +383,34 @@ under the iterators, so use the
@code{FOR_EACH_IMM_USE_STMT} and
sanity of the use list by moving all the uses for a statement into
a controlled position, and then iterating over those uses. Then the
optimization can manipulate the stmt when all the uses have been
-processed. This is a little slower than the FAST version since it adds a
-placeholder element and must sort through the list a bit for each statement.
-This placeholder element must be also be removed if the loop is
-terminated early; a destructor takes care of that when leaving the
-@code{FOR_EACH_IMM_USE_STMT} scope.
+processed. Only the current active @code{imm_use_p} may be altered
+when using an inner @code{FOR_EACH_IMM_USE_ON_STMT} iteration.
+You have to be careful to not inadvertedly modify the immediate
+use list by working on another stmt than the the current @code{stmt} during
+the iteration. In particular calling @code{update_stmt} is destructive
+on all SSA uses immediate use lists related to the updated stmt.
+This slower than the FAST version since it sorts through the list for each
+statement.
+
+@code{FOR_EACH_IMM_USE_ON_STMT} iteration may not be nested inside
+another @code{FOR_EACH_IMM_USE_ON_STMT} or @code{FOR_EACH_IMM_USE_FAST}
+iteration of the same immediate use list.
+
+There is the @code{gather_imm_use_stmts} helper that trades memory for
+removing the need to care about the immediate use list consistency and
+which also avoids duplicate visiting of stmts that can occur with
+@code{FOR_EACH_IMM_USE_FAST} when there are multiple uses of an SSA name
+on a stmt. This can be used to iterate safely over all use stmts like
+this:
+
+@smallexample
+ tree ssa_var;
+
+ for (gimple *use_stmt : gather_imm_use_stmts (ssa_var))
+ @{
+ // do something with use_stmt
+ @}
+@end smallexample
I was going to suggest some clarification here, but as I worked through
it, im not sure how to make it much clearer. :-P
I think the changes are all good.
Andrew
There are checks in @code{verify_ssa} which verify that the immediate use list
is up to date.
diff --git a/gcc/ssa-iterators.h b/gcc/ssa-iterators.h
index d6bd15c8ade..47220c5ce25 100644
--- a/gcc/ssa-iterators.h
+++ b/gcc/ssa-iterators.h
@@ -42,10 +42,10 @@ along with GCC; see the file COPYING3. If not see
Safe iteration via FOR_EACH_IMM_USE_STMT and FOR_EACH_IMM_USE_ON_STMT
allows insertion, deletion, and modification of SSA operands within
the current stmt iterated. The iterator manages this by re-sorting
- the immediate uses to batch uses on a single stmt after each other
- and inserts a marker node into the list immediately after the node
- ending the current batch. This marker node is uniquely identified by
- having null stmt *and* a null use pointer. */
+ the immediate uses to batch uses on a single stmt after each other.
+ If using an inner FOR_EACH_IMM_USE_ON_STMT iteration only the active
+ use may be manipulated. Safety relies on new immediate uses being
+ inserted at the front of immediate use lists. */
struct imm_use_iterator
{