https://gcc.gnu.org/g:1bf4a46e9b5c2253afba434895e071ed0e95fc93

commit r17-918-g1bf4a46e9b5c2253afba434895e071ed0e95fc93
Author: Roger Sayle <[email protected]>
Date:   Thu May 28 20:56:27 2026 +0100

    tree-ssa: Loop store motion micro-optimizations.
    
    ref_always_accessed_p is (currently) only ever called with stored_p being
    true, so specializing for this case, renaming ref_always_accessed{,_p} to
    ref_always_stored{,_p} saves storage and some redundant checks at run-time.
    
    2026-05-28  Roger Sayle  <[email protected]>
    
    gcc/ChangeLog
            * tree-ssa-loop-im.cc (ref_always_accessed_p): Rename to...
            (ref_always_stored_p): New function specialized to determine if
            REF is a store that is always executed in LOOP.
            (execute_sm): Use ref_always_stored_p instead of
            ref_always_accessed_p.
            (class ref_always_accessed): Rename to..
            (class ref_always_stored): Remove (always true) stored_p field.
            (ref_always_stored::operator ()): Always check for a store.
            Move hash table lookup, get_lim_data, after store test.
            (can_sm_ref_p): Use ref_always_stored_p insead of
            ref_always_accessed_p.

Diff:
---
 gcc/tree-ssa-loop-im.cc | 41 ++++++++++++++++-------------------------
 1 file changed, 16 insertions(+), 25 deletions(-)

diff --git a/gcc/tree-ssa-loop-im.cc b/gcc/tree-ssa-loop-im.cc
index 2651e3919e3a..d67782d1ff50 100644
--- a/gcc/tree-ssa-loop-im.cc
+++ b/gcc/tree-ssa-loop-im.cc
@@ -261,7 +261,7 @@ static bitmap_obstack lim_bitmap_obstack;
 static obstack mem_ref_obstack;
 
 static bool ref_indep_loop_p (class loop *, im_mem_ref *, dep_kind);
-static bool ref_always_accessed_p (class loop *, im_mem_ref *, bool);
+static bool ref_always_stored_p (class loop *, im_mem_ref *);
 static bool refs_independent_p (im_mem_ref *, im_mem_ref *, bool = true);
 
 /* Minimum cost of an expensive expression.  */
@@ -2319,7 +2319,7 @@ execute_sm (class loop *loop, im_mem_ref *ref,
   fmt_data.orig_loop = loop;
   for_each_index (&ref->mem.ref, force_move_till, &fmt_data);
 
-  bool always_stored = ref_always_accessed_p (loop, ref, true);
+  bool always_stored = ref_always_stored_p (loop, ref);
   if (maybe_mt
       && (bb_in_transaction (loop_preheader_edge (loop)->src)
          || (ref_can_have_store_data_races (ref->mem.ref) && ! always_stored)
@@ -3104,36 +3104,29 @@ hoist_memory_references (class loop *loop, bitmap 
mem_refs,
     delete (*iter).second;
 }
 
-class ref_always_accessed
+class ref_always_stored
 {
 public:
-  ref_always_accessed (class loop *loop_, bool stored_p_)
-      : loop (loop_), stored_p (stored_p_) {}
+  ref_always_stored (class loop *loop_)
+      : loop (loop_) {}
   bool operator () (mem_ref_loc *loc);
   class loop *loop;
-  bool stored_p;
 };
 
 bool
-ref_always_accessed::operator () (mem_ref_loc *loc)
+ref_always_stored::operator () (mem_ref_loc *loc)
 {
-  class loop *must_exec;
+  /* Make sure the statement is a store.  */
+  tree lhs = gimple_get_lhs (loc->stmt);
+  if (!lhs
+      || !(DECL_P (lhs) || REFERENCE_CLASS_P (lhs)))
+    return false;
 
   struct lim_aux_data *lim_data = get_lim_data (loc->stmt);
   if (!lim_data)
     return false;
 
-  /* If we require an always executed store make sure the statement
-     is a store.  */
-  if (stored_p)
-    {
-      tree lhs = gimple_get_lhs (loc->stmt);
-      if (!lhs
-         || !(DECL_P (lhs) || REFERENCE_CLASS_P (lhs)))
-       return false;
-    }
-
-  must_exec = lim_data->always_executed_in;
+  class loop *must_exec = lim_data->always_executed_in;
   if (!must_exec)
     return false;
 
@@ -3144,14 +3137,12 @@ ref_always_accessed::operator () (mem_ref_loc *loc)
   return false;
 }
 
-/* Returns true if REF is always accessed in LOOP.  If STORED_P is true
-   make sure REF is always stored to in LOOP.  */
+/* Returns true if REF is always stored in LOOP.  */
 
 static bool
-ref_always_accessed_p (class loop *loop, im_mem_ref *ref, bool stored_p)
+ref_always_stored_p (class loop *loop, im_mem_ref *ref)
 {
-  return for_all_locs_in_loop (loop, ref,
-                              ref_always_accessed (loop, stored_p));
+  return for_all_locs_in_loop (loop, ref, ref_always_stored (loop));
 }
 
 /* Returns true if LOAD_REF and STORE_REF form a "self write" pattern
@@ -3384,7 +3375,7 @@ can_sm_ref_p (class loop *loop, im_mem_ref *ref)
         stored to later anyway.  So this would only guard
         the load we need to emit.  Thus when the ref is not
         loaded we can elide this completely?  */
-      && !ref_always_accessed_p (loop, ref, true))
+      && !ref_always_stored_p (loop, ref))
     return false;
 
   /* Verify all loads of ref can be hoisted.  */

Reply via email to