The following adds a helper function to gather SSA use stmts without
duplicates. It steals the only padding bit in gimple to be a
"infrastructure local flag" which should be used only temporarily
and kept cleared. I did not add accessor functions for the flag
to not encourage (ab-)uses.
I have used an auto_vec<gimple *, 2> in the API to avoid heap
allocations for most cases (without doing statistics). I have
verified GCC 7 performs NRV optimization on the copy but I'll
note while auto_vec<gimple *> has copy and assign deleted,
auto_vec<gimple *, N> does not. Adding them breaks pair-fusion.cc
compile. Without using 'auto' or range-for the API use is a bit
awkward as that exposes the number of auto-allocated elements.
The helper can be used in a range-for, see the followup for an
example.
Bootstrapped and tested on x86_64-unknown-linux-gnu.
OK?
With this and 2/2 replacing the previous forwprop fix the SSA imm
use iterator checking patch bootstraps and tests OK (but as Andrew
noticed there's likely similar issues elsewhere). I'll rework
the checking patch now.
* gimple.h (gimple::pad): Rename to ...
(gimple::ilf): ... this.
* ssa-iterators.h (gather_imm_use_stmts): Declare.
* tree-ssa-operands.cc (gather_imm_use_stmts): New function.
---
gcc/gimple.h | 4 ++--
gcc/ssa-iterators.h | 5 +++++
gcc/tree-ssa-operands.cc | 20 ++++++++++++++++++++
3 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 0356bc52a5b..9bd3f8c0197 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -250,8 +250,8 @@ struct GTY((desc ("gimple_statement_structure (&%h)"), tag
("GSS_BASE"),
/* Nonzero if this statement contains volatile operands. */
unsigned has_volatile_ops : 1;
- /* Padding to get subcode to 16 bit alignment. */
- unsigned pad : 1;
+ /* Infrastructure local flag. Always clear. */
+ unsigned ilf : 1;
/* The SUBCODE field can be used for tuple-specific flags for tuples
that do not require subcodes. Note that SUBCODE should be at
diff --git a/gcc/ssa-iterators.h b/gcc/ssa-iterators.h
index 25569a79570..f83731234b1 100644
--- a/gcc/ssa-iterators.h
+++ b/gcc/ssa-iterators.h
@@ -116,6 +116,11 @@ struct auto_end_imm_use_stmt_traverse
(void) ((DEST) = next_imm_use_on_stmt (&(ITER))))
+/* Use this to get a vector of all gimple stmts using SSAVAR without
+ duplicates. It's cheaper than FOR_EACH_IMM_USE_STMT and has no
+ constraints on what you are allowed to do inside an iteration
+ over the vector. */
+extern auto_vec<gimple *, 2> gather_imm_use_stmts (tree ssavar);
extern bool single_imm_use_1 (const ssa_use_operand_t *head,
use_operand_p *use_p, gimple **stmt);
diff --git a/gcc/tree-ssa-operands.cc b/gcc/tree-ssa-operands.cc
index da0ba7ae017..6ea1e62d06d 100644
--- a/gcc/tree-ssa-operands.cc
+++ b/gcc/tree-ssa-operands.cc
@@ -1416,3 +1416,23 @@ single_imm_use_1 (const ssa_use_operand_t *head,
return single_use;
}
+/* Gather all stmts SSAVAR is used on, eliminating duplicates. */
+
+auto_vec<gimple *, 2>
+gather_imm_use_stmts (tree ssavar)
+{
+ auto_vec<gimple *, 2> stmts;
+ imm_use_iterator iter;
+ use_operand_p use_p;
+ FOR_EACH_IMM_USE_FAST (use_p, iter, ssavar)
+ {
+ gimple *use_stmt = USE_STMT (use_p);
+ if (use_stmt->ilf)
+ continue;
+ use_stmt->ilf = 1;
+ stmts.safe_push (use_stmt);
+ }
+ for (gimple *use_stmt : stmts)
+ use_stmt->ilf = 0;
+ return stmts;
+}
--
2.51.0