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.
* 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.
/* 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
(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);
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;
+}